您的位置:首页 > 移动开发 > Cocos引擎

cocos2dx editbox优化

2015-11-29 14:38 549 查看
最近刚刚工作 开一个博客记录工作中遇到的困难 也可以帮助别人少走一点弯路。

最近在做一款麻将的游戏,用的是cocos2dx的引擎,大家应该都知道,cocos2dx的输入框有很多,有editbox,textfield,但是每一种都有缺陷,比如有的不支持多行,不支持换行,支持换行的不支持光标,等等,真是坑的不行,自己也在网上找了一些办法,大部分都是重新封装一个输入框,但是其实作为比较少量的文本输入,例如用户名和密码之类的,editbox可以很好的解决,而且是它的底层是分平台实现的,所以在一些少量文本框的输入上就使用了 editbox,然而在android上运行完美,在ios上出了问题,因为可能cocos2dx的团队为了做一些屏幕的适配,导致在输入时输入框里面的字缩小为原来的一半



黑色区域即为正常时候显示的区域,红色的区域即为当你正在输入时显示的区域,宽和高大概都小了一半,那么自体也就变小了一半,而你输入完时就又变回了正常的大小,即黑色区域的大小。而且,这种变化还是分机型的,在ipad上面就不会变,而在ipadair上面就会变小,再iphone6s上也会变小,所以我就想到了是不是可能由于分辨率的缘故导致的,可能是由于cocos2dx的自动缩放导致的,所以我便开启了查代码之旅。

首先找到cocos2dx的editbox的ios实现,即UIEditBoxImpl-ios.mm,由于是在点击输入的时候出现的问题,所以自然而然地找到了这样一个函数:

void EditBoxImplIOS::openKeyboard()
{
_label->setVisible(false);
_labelPlaceHolder->setVisible(false);

_systemControl.textField.hidden = NO;
[_systemControl openKeyboard];
}


看到这里大家应该猜出来了,并不是再输入的时候对输入框进行缩放,而是在输入时将两个label隐藏,显示ios系统提供的textfield,那么这就可以看出来cocos2dx的editbox是由两个label和一个系统的textfield构成的,其中_label是用来显示输入的文字的,_labelPlaceHolder是用来显示当输入框没有文字时的占位符的,而textfield则是用来输入的,那么既然不是缩放,那么就是一开始初始化的时候初始化的值不对,那么继续找textfield的初始化

找到了两个函数

void EditBoxImplIOS::setContentSize(const Size& size)
{
_contentSize = size;
CCLOG("[Edit text] content size = (%f, %f)", size.width, size.height);
placeInactiveLabels();
auto glview = cocos2d::Director::getInstance()->getOpenGLView();
CGSize controlSize = CGSizeMake(size.width * glview->getScaleX(),size.height * glview->getScaleY());

CCEAGLView *eaglview = static_cast<CCEAGLView *>(glview->getEAGLView());
float factor = eaglview.contentScaleFactor;
controlSize.width /= factor;
controlSize.height /= factor;

[_systemControl setContentSize:controlSize];
}


{
bool isValidFontName = true;
if(pFontName == NULL || strlen(pFontName) == 0) {
isValidFontName = false;
}

CCEAGLView *eaglview = static_cast<CCEAGLView *>(cocos2d::Director::getInstance()->getOpenGLView()->getEAGLView());
float retinaFactor = eaglview.contentScaleFactor;
NSString * fntName = [NSString stringWithUTF8String:pFontName];

auto glview = cocos2d::Director::getInstance()->getOpenGLView();

float scaleFactor = glview->getScaleX();
UIFont *textFont = nil;
if (isValidFontName) {
textFont = [UIFont fontWithName:fntName size:fontSize * scaleFactor / retinaFactor];
}

if (!isValidFontName || textFont == nil){
textFont = [UIFont systemFontOfSize:fontSize * scaleFactor / retinaFactor];
}

if(textFont != nil) {
[_systemControl.textField setFont:textFont];
}

_label->setSystemFontName(pFontName);
_label->setSystemFontSize(fontSize);
}


setContentsize是设置editbox的size的 可以看到

CGSize controlSize = CGSizeMake(size.width * glview->getScaleX(),size.height * glview->getScaleY());
CCEAGLView *eaglview = static_cast<CCEAGLView *>(glview->getEAGLView());
float factor = eaglview.contentScaleFactor;
controlSize.width /= factor;
controlSize.height /= factor;

[_systemControl setContentSize:controlSize];


可以看到controlsize的width和height显示乘了一个glview->getScale(),然后除了factor,这是怎么回事,于是乎百度,

ContentScaleFactor是指ResourcesSize 和 designResolutionSize的比例系数,又凌乱了,资源的Size,用的是哪个资源。。这个真心不懂,希望有大神能解释一下,并没有设置过资源的size,界面使用cocosstudio搭建的,于是不打算弄了,而glview->getScale()也一直为1,于是把factor直接设置成1,也罢setfontsize的factor设为一,ipadair和ipad都好了,但是iphone6又打了将近二倍,额,无奈,做了一个机型判断,iphone设为0.6,都可以了,但是iphone4还是稍微有一些大,不过也就这样了,暂时算是解决了。

后来又看了看ContentScaleFactor的知识,还是不懂,但是把所有机型的都输出了一遍,发现iphone6 plus是3 iphone6和ipadair是2,ipad是1,后来又看了一下各机型分辨率,发现iphone都是按一定倍数增长的,ipad也是按照一定倍数增长的,只不过最小公约数不一样,由于我们的资源是1024*768的,所以ipad就没有缩放,ContentScaleFactor为1,ipadair刚好是其二倍,所以ContentScaleFactor为二,但是好像已经自动缩放,不用修改大小就可以从ipad适配到ipadair,不明白为什么要除ContentScaleFactor,同理,iphone各机型也不需要做大小改变就可以自动适配,于是就做了一个版本判断就ok了,但是既然这么写一定有其原因的,我还是太年轻。。。。。,有知道的可以告诉我,谢谢了,就说这么多,第一篇博客,如有错误,欢迎指出。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息