這個文章的名字起的實在是有點長,主要是怕說不清楚。
在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 }