[iOS?] CCEditBox internal textbox does not move with parent node


#1

Hi all,

First I must say that I’m loving the API, and has become a staple in my programming life. While working with it I have come across a bit of a problem and just wanting to document it, as well as get some insight on where to fix it.

I’m currently developing on iOS, but wondering if this might be across all platforms. The problem came about when I have a layer transition and a CCEditBox with placeholder text. When the parent layer moves in from offscreen - the placeholder text, as well as any text entered, will pop onto the screen and not animate in with the rest of the CCEditBox and layer.

In some quick test I’ve done the text does follow around with the edit box if a move action is run on it - but not if it’s parent node is the one moving.

Is there a simple method I need to inherit/override to fix this? or is the problem a bit deeper?

I’m using the 2.0.4 codebase for this project.

Thanks


#2

Yes, CCEditBox for iOS now still have some issues. That mainly because the implementation of CCEditBox on iOS is different from other platforms like Android.
On iOS, it uses a system UI control (UITextField) to cover on CCControlButton. So when doing a transition operation for a scene which contains a CCEditBox, the problem will come.
For short-term solution, plz don’t use transition for the scene which contains a CCEditBox. Thank you.


#3

Hi James,

Thanks for the reply, and I have noticed a few other things that I’m planning on fixing up - and then putting up for review once I figure it out (fairly new to git). I’ve managed to get the placeholder colouring to work, but if it is changed without the placeholder text changing it will not update yet.

I’m really needing this fixed for the project I’m working on, and have no troubles in doing it myself - just looking for some pointers :slight_smile: And I’ll be sure to report back with anything i get working


#4

OK, after you fix that, just let me know, i will help you to send Pull Request on the github. Thanks.

Dan Silk wrote:

Hi James,
>
Thanks for the reply, and I have noticed a few other things that I’m planning on fixing up - and then putting up for review once I figure it out (fairly new to git). I’ve managed to get the placeholder colouring to work, but if it is changed without the placeholder text changing it will not update yet.
>
I’m really needing this fixed for the project I’m working on, and have no troubles in doing it myself - just looking for some pointers :slight_smile: And I’ll be sure to report back with anything i get working


#5

Just to keep them all in the same thread - I’ve come across another issue.

If you have anything on top of the editbox, the UITextField text will render on top of that again, instead of underneath it. On first look this might not be an easy solve problem as the text field view is placed on top of the open GL one (if I’m correct).

Anyone have any insight to this issue?


#6

Hello,

I’ve been stumbling on this issue as well. The problem is that UITextField is not part of the OpenGL View, and globally not part of the whole CCnode hierarchy. The easiest solution out of it would be to change this method :

void CCEditBoxImplIOS::setPosition(const CCPoint& pos)
{
    //TODO should consider anchor point, the default value is (0.5, 0,5)
    [GET_IMPL setPosition:convertDesignCoordToScreenCoord(ccp(pos.x-m_tContentSize.width/2, pos.y+m_tContentSize.height/2), m_bInRetinaMode)];
}

Here, you should not use pos but rather take a look at the whole hierarchy to resolve its real position before passing it to convertDesignCoordToScreenCoord.

To get the real position, I did a similar algorithm (to save you the trouble), which is about :

    CCPoint realPosition = obj->getPosition();
    CCNode* parent = getParent(obj);
    while(parent != NULL)
    {
        realPosition.x = realPosition.x * parent->getScaleX() + parent->getPosition().x;
        realPosition.y = realPosition.y * parent->getScaleY() + parent->getPosition().y;
        parent = getParent(parent);
    }
    //here, you get the real position to assign to m_pEditBoxImpl

The only problem point is to implement the getParent method, which should return NULL if there is no parent. That would be easy to get from a CCNode, but how do you pass that CCNode to the CCEditBoxImpl in a clean way ? Or should that calculation be done by the CCEditBox for iOS only ?

As for the problem of UITextField being always on top, it’s not an easily solved problem. When you using any other UIView, it will be either on top or under OpenGL View. There can not be any UIView in “the middle” of an OpenGL View. Some hack around it would be :

  • replace by a cocos label when you are not editing so that the label is in the cocos hierarchy for that time. It obviously involve quite a bit of fiddling to look good all the time and may not always fit in your context.
  • put the items you want on top of the UITextField on another UIView, not on OpenGL View (I don’t think it’s possible to have 2 separate OpenGL View) : you loose all cocos capabilities on those items, but it’ll be on top. It’s an easy solution if you just have a simple overlay for example.

As an aside, I spotted another problem with CCEditBox implementation on iOS (I didn’t try yet on Android) : there is a problem with the view moving in portrait mode : to be precise, if the CCEditBox is on the right part of the screen, the view will move properly, but if it’s on the left, the view won’t move (everything else working fine). I suspect the hit collision, at some point, is done only for landscape. I’ll try to get to the bottom of it.

Edit : this problem is actually caused by the very problem of that thread, and not portrait. I did a custom hack in my code to go around the problem, but the same issue has another side effect : in this method, the rect is not properly calibrated either, resulting to a miss :

void CCEditBox::keyboardWillShow(CCIMEKeyboardNotificationInfo& info)
{
    // CCLOG("CCEditBox::keyboardWillShow");
    CCRect rectTracked = getRect(this);

    // if the keyboard area doesn't intersect with the tracking node area, nothing needs to be done.
    if (!rectTracked.intersectsRect(info.end))
    {
        CCLOG("needn't to adjust view layout.");
        return;
    }
[...]

The issue comes from the getRect method which only look for current node position, instead of taking into account the hierarchy. The size should take into account scale and parents scale as well.


#7

Dan Silk wrote:

Hi all,
>
First I must say that I’m loving the API, and has become a staple in my programming life. While working with it I have come across a bit of a problem and just wanting to document it, as well as get some insight on where to fix it.
>
I’m currently developing on iOS, but wondering if this might be across all platforms. The problem came about when I have a layer transition and a CCEditBox with placeholder text. When the parent layer moves in from offscreen - the placeholder text, as well as any text entered, will pop onto the screen and not animate in with the rest of the CCEditBox and layer.
>
In some quick test I’ve done the text does follow around with the edit box if a move action is run on it - but not if it’s parent node is the one moving.
>
Is there a simple method I need to inherit/override to fix this? or is the problem a bit deeper?
>
I’m using the 2.0.4 codebase for this project.
>
Thanks

Right now this feature not here but you can manage with onEnterTransitionDidFinish(); add placeholder or text here and move back set it with balck
May this idea is helpful.
Thanks