CocoStudio UIButton setPressedActionEnabled 子控件缩放解决方案

来源:互联网 发布:淘宝如何避免售假违规 编辑:程序博客网 时间:2024/05/22 14:29

为什么子控件不跟着缩放

  • UIButton是个组合的控件,其主体是个Widget,里面有如下几个子控件:

    Scale9Sprite* _buttonNormalRenderer;    Scale9Sprite* _buttonClickedRenderer;    Scale9Sprite* _buttonDisabledRenderer;    Label* _titleRenderer;
  • 设置setPressedActionEnabled为true之后,主要的处理在onPressStateChangedToNormal和onPressStateChangedToPressed两个函数中,(基于v3.14.1)代码如下:

void Button::onPressStateChangedToNormal(){    _buttonNormalRenderer->setVisible(true);    _buttonClickedRenderer->setVisible(false);    _buttonDisabledRenderer->setVisible(false);    _buttonNormalRenderer->setState(Scale9Sprite::State::NORMAL);    if (_pressedTextureLoaded)    {        if (_pressedActionEnabled)        {            // 以下为操作代码            _buttonNormalRenderer->stopAllActions();            _buttonClickedRenderer->stopAllActions();//            Action *zoomAction = ScaleTo::create(ZOOM_ACTION_TIME_STEP, _normalTextureScaleXInSize, _normalTextureScaleYInSize);            //fixme: the zoomAction will run in the next frame which will cause the _buttonNormalRenderer to a wrong scale            _buttonNormalRenderer->setScale(1.0);            _buttonClickedRenderer->setScale(1.0);            if (nullptr != _titleRenderer)            {                _titleRenderer->stopAllActions();                if (_unifySize)                {                    Action *zoomTitleAction = ScaleTo::create(ZOOM_ACTION_TIME_STEP, 1.0f, 1.0f);                    _titleRenderer->runAction(zoomTitleAction);                }                else                {                    _titleRenderer->setScaleX(1.0f);                    _titleRenderer->setScaleY(1.0f);                }            }        }    }    else    {        _buttonNormalRenderer->stopAllActions();        _buttonNormalRenderer->setScale(1.0);        if (nullptr != _titleRenderer)        {            _titleRenderer->stopAllActions();            _titleRenderer->setScaleX(1.0f);            _titleRenderer->setScaleY(1.0f);        }    }}

void Button::onPressStateChangedToPressed(){    _buttonNormalRenderer->setState(Scale9Sprite::State::NORMAL);    if (_pressedTextureLoaded)    {        _buttonNormalRenderer->setVisible(false);        _buttonClickedRenderer->setVisible(true);        _buttonDisabledRenderer->setVisible(false);        if (_pressedActionEnabled)        {            // 不操作子控件            _buttonNormalRenderer->stopAllActions();            _buttonClickedRenderer->stopAllActions();            Action *zoomAction = ScaleTo::create(ZOOM_ACTION_TIME_STEP,                                                 1.0f + _zoomScale,                                                 1.0f + _zoomScale);            _buttonClickedRenderer->runAction(zoomAction);            _buttonNormalRenderer->setScale(1.0f + _zoomScale,                                            1.0f + _zoomScale);            if (nullptr != _titleRenderer)            {                _titleRenderer->stopAllActions();                Action *zoomTitleAction = ScaleTo::create(ZOOM_ACTION_TIME_STEP,                                                          1.0f + _zoomScale, 1.0f + _zoomScale);                _titleRenderer->runAction(zoomTitleAction);            }        }    }    else    {        _buttonNormalRenderer->setVisible(true);        _buttonClickedRenderer->setVisible(true);        _buttonDisabledRenderer->setVisible(false);        _buttonNormalRenderer->stopAllActions();        _buttonNormalRenderer->setScale(1.0f +_zoomScale, 1.0f + _zoomScale);        if (nullptr != _titleRenderer)        {            _titleRenderer->stopAllActions();            _titleRenderer->setScaleX(1.0f + _zoomScale);            _titleRenderer->setScaleY(1.0f + _zoomScale);        }    }}

代码中,只对UIButton的4个子控件进行了操作,所以其他子控件并不会跟着缩放。

  • 之前有一些解决方案,是调用UIButton的getChildren()函数,遍历子节点,然后修改scale使其达到缩放的目的,但多数是写死了其放大后的比例,一但子控件本身有缩放就会出现问题,参考:子控件不跟着缩放。

  • 即使通过一些方法记住子控件的原缩放比,若子控件比较靠近UIButton的边缘,仍然会发现子控件好像在浮动的现象,这是因为scale变了,子控件相对UIButton的position位置没有变导致的。

较完美的解决方案

  • 既然都是UIButton的子控件,为什么缩放时要缩放子控件呢?直接缩放UIButton本身不就可以了嘛。
  • 按照以上思路,1. 要记住UIButton的原比例;2. 不再操作子控件,直接操作UIButton。代码如下(origin拼写错误请各位忽略:joy: ):

/** * CCNode.h */float _orignScale;              ///< origin scaling factor, just for UIButtonvirtual void setOrignScale(float scale);virtual float getOrignScale() const;/** * CCNode.cpp * 增加orignScale */// original scale getterfloat Node::getOrignScale(void) const{    return _orignScale;}// original scale settervoid Node::setOrignScale(float scale){    _orignScale = scale;}

/** * UIButton.cpp */void Button::onPressStateChangedToNormal(){    _buttonNormalRenderer->setVisible(true);    _buttonClickedRenderer->setVisible(false);    _buttonDisabledRenderer->setVisible(false);    _buttonNormalRenderer->setState(Scale9Sprite::State::NORMAL);    if (_pressedTextureLoaded)    {        if (_pressedActionEnabled)        {            // 不操作子控件//            _buttonNormalRenderer->stopAllActions();//            _buttonClickedRenderer->stopAllActions();//            Action *zoomAction = ScaleTo::create(ZOOM_ACTION_TIME_STEP, _normalTextureScaleXInSize, _normalTextureScaleYInSize);            //fixme: the zoomAction will run in the next frame which will cause the _buttonNormalRenderer to a wrong scale//            _buttonNormalRenderer->setScale(1.0);//            _buttonClickedRenderer->setScale(1.0);//            if (nullptr != _titleRenderer)//            {//                _titleRenderer->stopAllActions();//                if (_unifySize)//                {//                    Action *zoomTitleAction = ScaleTo::create(ZOOM_ACTION_TIME_STEP, 1.0f, 1.0f);//                    _titleRenderer->runAction(zoomTitleAction);//                }//                else//                {//                    _titleRenderer->setScaleX(1.0f);//                    _titleRenderer->setScaleY(1.0f);//                }//            }                        // 直接缩放UIButton控件            this->stopAllActions();            float orignScale = this->getOrignScale();            float childScale = (orignScale == -1.0f ? this->getScale() : orignScale);            this->setScale(childScale);        }    }    else    {        _buttonNormalRenderer->stopAllActions();        _buttonNormalRenderer->setScale(1.0);        if (nullptr != _titleRenderer)        {            _titleRenderer->stopAllActions();            _titleRenderer->setScaleX(1.0f);            _titleRenderer->setScaleY(1.0f);        }    }}

/** * UIButton.cpp */void Button::onPressStateChangedToPressed(){    _buttonNormalRenderer->setState(Scale9Sprite::State::NORMAL);    if (_pressedTextureLoaded)    {        _buttonNormalRenderer->setVisible(false);        _buttonClickedRenderer->setVisible(true);        _buttonDisabledRenderer->setVisible(false);        if (_pressedActionEnabled)        {            // 不操作子控件//            _buttonNormalRenderer->stopAllActions();//            _buttonClickedRenderer->stopAllActions();////            Action *zoomAction = ScaleTo::create(ZOOM_ACTION_TIME_STEP,//                                                 1.0f + _zoomScale,//                                                 1.0f + _zoomScale);//            _buttonClickedRenderer->runAction(zoomAction);////            _buttonNormalRenderer->setScale(1.0f + _zoomScale,//                                            1.0f + _zoomScale);////            if (nullptr != _titleRenderer)//            {//                _titleRenderer->stopAllActions();//                Action *zoomTitleAction = ScaleTo::create(ZOOM_ACTION_TIME_STEP,//                                                          1.0f + _zoomScale, 1.0f + _zoomScale);//                _titleRenderer->runAction(zoomTitleAction);//            }                        // 直接缩放UIButton控件            this->stopAllActions();            float orignScale = this->getOrignScale();            float childScale = (orignScale == -1.0f ? this->getScale() : orignScale);            this->setOrignScale(childScale);                        Action *zoomChildAction = ScaleTo::create(ZOOM_ACTION_TIME_STEP,                                                      childScale * (1.0f + _zoomScale),                                                      childScale * (1.0f + _zoomScale));            this->runAction(zoomChildAction);        }    }    else    {        _buttonNormalRenderer->setVisible(true);        _buttonClickedRenderer->setVisible(true);        _buttonDisabledRenderer->setVisible(false);        _buttonNormalRenderer->stopAllActions();        _buttonNormalRenderer->setScale(1.0f +_zoomScale, 1.0f + _zoomScale);        if (nullptr != _titleRenderer)        {            _titleRenderer->stopAllActions();            _titleRenderer->setScaleX(1.0f + _zoomScale);            _titleRenderer->setScaleY(1.0f + _zoomScale);        }    }}
  • 已知缺陷:
    1. 在执行点击事件之后,如果需要变更UIButton的scale缩放比,originScale需要手动置为初始值,否则,再次点击之后会重新设置为之前的缩放比。有啥好的想法一起交流一下~
原创粉丝点击