the key to resolve this is :
In the scroll view ,
A. the scroll layer should handle the touch event , when it recieve the touch event, it should detect the does the visible rect contains the touch point
B. if it contains , it shoud send the event to it’s child,
C. and if doesn’t contains ,it should make the event continue bubble……but except it’s children
So I look the source code ,I found
- CCScrollView have a touch priority 0 by default
- CCControls have a touch priority 1 by default
that means the scrollview always handle the touch event first
bool CCScrollView::ccTouchBegan(CCTouch* touch, CCEvent* event)
{
if (!this~~>isVisible)
{
return false;
}
CCRect frame = getViewRect;
//dispatcher does not know about clipping. reject touches outside visible bounds.
if > 2 ||
m_bTouchMoved ||
!frame.containsPoint)))
{
return false;
}
if )
{
m_pTouches~~>addObject(touch);
}
if (m_pTouches~~>count 1)
{ // scrolling
m_tTouchPoint = this->convertTouchToNodeSpace(touch);
m_bTouchMoved = false;
m_bDragging = true; //dragging started
m_tScrollDistance = ccp(0.0f, 0.0f);
m_fTouchLength = 0.0f;
}
else if (m_pTouches->count() 2)
{
m_tTouchPoint = ccpMidpointm_pTouches~~>objectAtIndex(0)),
this~~>convertTouchToNodeSpacem_pTouches~~>objectAtIndex(1)));
m_fTouchLength = ccpDistance(m_pContainer~~>convertTouchToNodeSpacem_pTouches~~>objectAtIndex(0)),
m_pContainer~~>convertTouchToNodeSpacem_pTouches~~>objectAtIndex(1)));
m_bDragging = false;
}
return true;
}
and when touch is in the visible area it’s returns true to claimed the touch to perform scroll behaviour , otherwise it’s returns false.
but it’s doesn’t matter, case it register a targetDelegate with swallowTouches false,the touch event is bubble always
So if you touch a button in the scroller’s visible area, the scroll and the button both handle the touch event ,scroll first and the button second, there is no problem
but when you click the button in the scroll but in the invisible area, in the scroll’s touchBegin,the scroll will check if the touch point in the visible bounds,
if not, it will return false and doesn’t claim the touch began event and also will not perform scroll
CCRect frame = getViewRect();
//dispatcher does not know about clipping. reject touches outside visible bounds.
if (m_pTouches->count() > 2 ||
m_bTouchMoved ||
!frame.containsPoint(m_pContainer->convertToWorldSpace(m_pContainer->convertTouchToNodeSpace(touch))))
{
return false;
}
but at this time , the touch began will bubble to the button, it will respond to the touch began event……. and also respond to the tap ……… it’s wrong
And I think there are two ways to resolve this problem
- when the child receive touch event , there are some method to tell the visible rect of it’s self, and it will check if the touch point in the rect,yes it’s respond, no ignored
But I don’t know there is a method to do this……
- scroll handle the touch event , and when the touch is not in it’s visible area,it will not bubble the event to it’s children,only children.
But in the CCTouchDispatcher the m_pTargetedHandlers don’t have a inheritance structure
So, I don’t have an idea to resolve this