CCScrollView上和按钮相关的两个bug
Cocos2d-x的触摸处理机制有点不好用(当然据说在最新的3里面已经彻底改掉了),基本上就是只要你监听了触摸事件,那么当触摸发生的时候,dispatcher就会把这个消息发给所有监听了这个消息的人,任何控件都无法截获某个消息并阻止后面的响应;而且不管这个触摸是不是在你的内容范围,只要你注册了就能收到。
具体来说,我们在CCScrollView上放了按钮之后,会有两个bug:
1. 被CCScrollView剪切掉的不可见按钮仍然会响应。
如果高优先级的可以吞噬消息的话,那么我们直接让优先级比较高的CCScrollView把这个消息吞掉就好了,如果有其他ScrollView外面的按钮需要响应,那么让他们的优先级比ScrollView更高即可。
2. 如果CCScrollView上的按钮已经响应触摸,进入被touch的状态了,现在我们开始拖拽,这时候这个按钮应该被取消,不再响应,同时让CCScrollView开始拖动。
同理,我们可以通过让CCScrollView吞噬这个消息来让按钮不再继续响应。
具体我们是这么做的:
1. 在CCNode里面增加了一个函数,用于判断自己是否是某个CCNode的后代,以及另一个函数,用于寻找自己最近的可以swallowtouch的祖先。这里只能加到CCNode里面,因为树形结构是在这里的。
2. 在CCTouch里面增加了一个CCArray,用于存放这个touch都有谁表示要吞掉了,之所以用数组是因为可能有多个CCScrollView想吞这个touch。
3. 当一个CCScrollView觉得要吞噬touch时(touch在可见范围外,开始拖动了),就把自己给设到这个touch里面去。
4. 在CCTouchDispatcher里面,对于每一个touch,对于所有监听对象,检测他们是不是宣称要吞噬touch的对象的后代,是的话则不进行dispatch。
5. 给CCTouchDelegateProtocol里面增加了一个maySwallowTouch的bool值,其余默认是false,不进行这个检测,CCScrollView设成true,上面回溯的时候只检测可能吞噬的节点。
6. 对于拖动取消的按钮,在取消的时候,fake一个touchcancel的event给他,这里有个问题是这种做法在CCControlButton里面,会导致touchcancel的event触发。
大概就这样,要放假了,来不及详细写拉~~~