转载请注明地址:http://www.jb51.cc/article/p-nsewocfp-mg.html
CCTouchDispatcher中是这样分发触摸事件的:
CCARRAY_FOREACH(m_pTargetedHandlers,pObj)//这里是遍历了一个注册过触摸事件的数组,按优先级排序 { pHandler = (CCTargetedTouchHandler *)(pObj); if (! pHandler) { break; } bool bClaimed = false; if (uIndex == CCTOUCHBEGAN) { bClaimed = pHandler->getDelegate()->ccTouchBegan(pTouch,pEvent); if (bClaimed) { pHandler->getClaimedTouches()->addObject(pTouch); } } else if (pHandler->getClaimedTouches()->containsObject(pTouch)) { // moved ended canceled bClaimed = true; switch (sHelper.m_type) { case CCTOUCHMOVED: pHandler->getDelegate()->ccTouchMoved(pTouch,pEvent); break; case CCTOUCHENDED: pHandler->getDelegate()->ccTouchEnded(pTouch,pEvent); pHandler->getClaimedTouches()->removeObject(pTouch); break; case CCTOUCHCANCELLED: pHandler->getDelegate()->ccTouchCancelled(pTouch,pEvent); pHandler->getClaimedTouches()->removeObject(pTouch); break; } } if (bClaimed && pHandler->isSwallowsTouches()) { if (bNeedsMutableSet) { pMutableTouches->removeObject(pTouch); } break; } }然后如果调用这里的 setPriority,就会重新排序数组: rearrangeHandlers
void CCTouchDispatcher::setPriority(int nPriority,CCTouchDelegate *pDelegate) { CCAssert(pDelegate != NULL,""); CCTouchHandler *handler = NULL; handler = this->findHandler(pDelegate); CCAssert(handler != NULL,""); if (handler->getPriority() != nPriority) { handler->setPriority(nPriority); this->rearrangeHandlers(m_pTargetedHandlers); this->rearrangeHandlers(m_pStandardHandlers); } }
但是在业务层调用的 setPriority是这样的:
void CCTouchHandler::setPriority(int nPriority) { m_nPriority = nPriority; }
所以你会发现如果在初始化一个控件的时候调用 setPriority就会有效,而在运行中动态更改就无效,就是因为初始化后的下一帧调用(调用onEnter时,会注册touchdelegate)会根据当前priority将其注册进那个数组:
void CCTouchDispatcher::forceAddHandler(CCTouchHandler *pHandler,CCArray *pArray) { unsigned int u = 0; CCObject* pObj = NULL; CCARRAY_FOREACH(pArray,pObj) { CCTouchHandler *h = (CCTouchHandler *)pObj; if (h) { if (h->getPriority() < pHandler->getPriority()) { ++u; } if (h->getDelegate() == pHandler->getDelegate()) { CCAssert(0,""); return; } } } pArray->insertObject(pHandler,u); }
所以,改变触摸分发数组的机会只有一次,之后如果想动态的改变优先级需要获取 TouchDispatcher后设置,或者类似menu可以调用现成的函数 setHandlerPriority