下面介绍一个跟触摸事件优先级层级关系的问题:
我自定义了一个精灵类,而且这个精灵类对象可以接收触摸事件;然后我还在这个自定义的精灵中添加了一个CCEditBox输入框。那么这个时候就要小心处理这二者之间接收触摸事件的优先级。
假如对自定义精灵注册触摸事件是:
CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 0, true);
注册的触摸优先级值是 0;
那么运行会发现,点击CCEditBox输入框的时候,并不会响应弹出键盘。
其实跟踪一下CCEditBox这个类就会发现,它也是继承自CCLayer,说明其要接收是否触摸到编辑输入框,当然也是注册了接收触摸事件;那么我们就可以将当前自定义精灵所注册的触摸事件优先级降低,进而自动的就让CCEditBox输入框的接收触摸优先级升高,这样就不会产生CCEditBox输入框不响应的问题了。
我们将自定义精灵注册触摸事件修改为:
CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 1, true);
运行发现,没问题哦!那么我们也就可以做一个不严谨的推测:CCEditBox输入框注册接收触摸事件的优先级是 0.
那么现在就可以在需要的Layer中添加这个自定义精灵的实例对象了。
假定现在这个Layer也要接收触摸事件,那么同样要进行注册。有了上面的经验,我们聪明的知道,Layer的触摸优先级应该是要比这个自定义精灵的优先级低,所以:
CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 2, true);
运行,发现,没有问题。
这个三个要接收触摸事件的优先级是这样的:(由高到底)CCEditBox,自定义精灵,Layer。(他们的优先级值是:0,1,2)注意优先级值和接收触摸事件的优先级是相反的,也就是说,优先级值越小,接收触摸事件的优先级越高。
似乎一切都运行正常没有问题了,但是!
假如你对这个自定义精灵进行一些操作结束后,想要移除这个自定义精灵,让当前这个Layer接收触摸消息的时候(注意:在这个例子中,当前的Layer添加了这个自定义精灵而且 bSwallowsTouches = true ,所以这个Layer是接收不到触摸消息的。);通常的做法就是要在Layer中先移除掉这个自定义精灵对象;
在自定义精灵类中: this->removeFromParent();
运行看看,哎呀,有问题!虽然这个自定义精灵消失了,但是Layer还是接收不到触摸事件。这个是神马问题和原因呢?
原来还要消除掉这个自定义精灵注册的接收触摸事件。那么在onExit方法中:
CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);
运行发现,还是不行,提示的错误大致是 CCEditBox 有点问题;哦,原来我们在自定义精灵中还有一个可以接收触摸事件的CCEditBox。那么怎么办呢?
在onExit中:
this->removeAllChildren();
CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);
终于就没有问题了。
总结:其实通过这个例子,我们可以发现,在整个接收触摸事件的处理过程中,体现的是一种层级模型:
CCEditBox |
自定义精灵 |
Layer |
注册的优先级值越小,那么接收触摸事件优先级越高,可以通过 设置 bSwallowsTouches 决定是否吃掉这个触摸事件,如果true,那么下面的就接收不到这个触摸事件了。
同样当你要让底层的节点接收到触摸事件,当然就要先移除掉上面的节点。
以上内容属于个人见解,如有错漏,欢迎高手不吝指正。