因为经常需要让事件穿透到下一层的scrollview.可在cocostudio 中默认并没有开启事件穿透.查看原代码看到直接setSwallowTouches为true了.
对UIWidget做出如下的处理
在UIWidget.h中加入三个成员变量用与控制事件穿透
//UIWidget.h中的改动
public:
/**
* Sets whether the widget swallow touches
* the default value is true
* @param needSwallow true if the widget is need to swallow touches
* @param always false if the widget will swallow touches only when hitTest success
*/
void setSwallowTouches(bool needSwallow,bool always = true);
private:
bool _swallowTouches;//控制是否需要穿透
bool _penetrateTouchesAlways;//用于决定是否总是穿透.
bool _hadMoveOutHitArea;//用于判断是否在移动过程中移出点击区域
//UIWidget.cpp中的改动
void Widget::setSwallowTouches(bool needSwallow,bool always/* = true*/)
{
if (_touchListener)
{
_touchListener->setSwallowTouches(needSwallow);
}
_swallowTouches = needSwallow;
_penetrateTouchesAlways = always;
}
bool Widget::onTouchBegan(Touch *touch, Event *unusedEvent)
{
_hitted = false;
if (isVisible() && isEnabled() && isAncestorsEnabled() && isAncestorsVisible(this) )
{
_touchBeganPosition = touch->getLocation();
if(hitTest(_touchBeganPosition) && isClippingParentContainsPoint(_touchBeganPosition))
{
_hitted = true;
}
}
if (!_hitted)
{
return false;
}
setHighlighted(true);
Widget* widgetParent = getWidgetParent();
if (widgetParent)
{
widgetParent->interceptTouchEvent(TouchEventType::BEGAN, this, touch);
}
pushDownEvent();
// if (!_penetrateTouchesAlways)
// {
// _touchListener->setSwallowTouches(true);
// log("beginning~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
// }
_hadMoveOutHitArea = false;
return true;
}
void Widget::onTouchMoved(Touch *touch, Event *unusedEvent)
{
_touchMovePosition = touch->getLocation();
if (hitTest(_touchMovePosition))
{
setHighlighted(true);
if (!_swallowTouches && !_penetrateTouchesAlways && !_hadMoveOutHitArea)
_touchListener->setSwallowTouches(true);
}
else
{
setHighlighted(false);
if (!_swallowTouches && !_penetrateTouchesAlways)
{
_touchListener->setSwallowTouches(false);
_hadMoveOutHitArea = true;
}
}
Widget* widgetParent = getWidgetParent();
if (widgetParent)
{
widgetParent->interceptTouchEvent(TouchEventType::MOVED, this, touch);
}
moveEvent();
}
void Widget::onTouchEnded(Touch *touch, Event *unusedEvent)
{
bool highlight = _highlight;
setHighlighted(false);
if (!_swallowTouches && !_penetrateTouchesAlways)
{
_touchListener->setSwallowTouches(false);
if (_hadMoveOutHitArea)
return;
}
_touchEndPosition = touch->getLocation();
Widget* widgetParent = getWidgetParent();
if (widgetParent)
{
widgetParent->interceptTouchEvent(TouchEventType::ENDED, this, touch);
}
if (highlight)
{
releaseUpEvent();
}
else
{
cancelUpEvent();
}
}