關於cocos2d-x 中 CCEditBox 的輸入位置和IOS虛擬鍵盤位置不重合的bug


這個文章的名字起的實在是有點長,主要是怕說不清楚。

在IOS上,輸入時,我看到過的比較少,就兩種,如附件兩張圖。一個是虛擬鍵盤的輸入框完全是在CCEditBox上,另一張虛擬鍵盤的輸入區域是緊挨着鍵盤的並且左對齊的。

我的cocos2d版本是2.1rc0-x-2.1.4,貌似是當前最新的。

因為項目需要,我使用了CCEditBox,實現一個聊天的功能。ipad上運行時發現,鍵盤自帶的輸入區域既不在CCEditBox上,也沒有緊挨着鍵盤左對齊。

這就是需要我們調整虛擬鍵盤輸入域的位置了。查看了CCEditBoxImplIOS.mm文件,發現方法adjustTextFieldPosition是調整這個文本域的位置的。看邏輯沒什么錯,為什么不是我需要的效果呢。

現在網上查,很多人說這是CCEditBox的bug,必須要把CCEditBox對象加到大小是全屏的父節點中。。。我暈,怎么可能,界面層級關系有要求,節點很多,父節點不可能是全屏的節點。 還有人說設置position的時候取父節點的position。還有人說必須要把CCEditBox先加到父節點中去,然后設置其position。這些我都嘗試了。發現,啥都沒用。

 

然后仔細研究了adjustTextFieldPosition方法,代碼如下。

1 void CCEditBoxImplIOS::adjustTextFieldPosition()
2 {
3     CCSize contentSize = m_pEditBox->getContentSize();
4     CCRect rect = CCRectMake(0, 0, contentSize.width, contentSize.height);
5     rect = CCRectApplyAffineTransform(rect, m_pEditBox->nodeToWorldTransform());
6     
7     CCPoint designCoord = ccp(rect.origin.x, rect.origin.y + rect.size.height);
8     [m_systemControl setPosition:convertDesignCoordToScreenCoord(designCoord, m_bInRetinaMode)];
9 }

其中第5行的nodeToWorldTransform方法代碼是這樣的,很明顯,都已經向上取了所有父節點來把當前節點的坐標進行轉換的。

1 CCAffineTransform CCNode::nodeToWorldTransform()
2 {
3     CCAffineTransform t = this->nodeToParentTransform();
4 
5     for (CCNode *p = m_pParent; p != NULL; p = p->getParent())
6         t = CCAffineTransformConcat(t, p->nodeToParentTransform());
7 
8     return t;
9 }

所以問題就在調用adjustTextFieldPosition方法的時機了。發現只在setPosition 和 onEnter 兩個方法里邊調用。這樣當你還沒有加入父節點時,nodeToWorldTransform方法的for循環其實起不了多大作用,就是沒法將你當前CCEditBox的坐標轉換為全屏這樣的坐標了。

所以我得解決方法是,在打開鍵盤時,也就是openKeyboard方法中調用adjustTextFieldPosition,結果完全OK了。

1 void CCEditBoxImplIOS::openKeyboard()
2 {
3     m_pLabel->setVisible(false);
4     m_pLabelPlaceHolder->setVisible(false);
5 
6     m_systemControl.textField.hidden = NO;
7     adjustTextFieldPosition();// add by elan 2013-07-24
8     [m_systemControl openKeyboard];
9 }

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM