Hello again
I haven’t been able to see how to get the offset of the inner container of ui::ScrollView
to translate touches to _innerContainer
.
On my real PC I can see my answer readily available in the code, at least in theory, in practice I am struggling to override onTouchBegan
in my ScrollView
subclass. I’ll list my conclusions here for future reference. The dilemna is when to return true/false from the ScrollView
subclass’s onTouchBegan
handler.
HelloScene : public Layer { //This always handles touches, just knows when the scrollView has popped up.
...
//In init/onEnter
auto listener = EventListenerTouchOneByOne::create();
// When "swallow touches" is true, then returning 'true' from the onTouchBegan method will "swallow" the touch event, preventing other listeners from using it.
listener->setSwallowTouches(true);
listener->onTouchBegan = CC_CALLBACK_2(HelloScene::onTouchBegan, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
...
//In my ScrollView subclass
bool MyListV::onTouchBegan(cocos2d::Touch* touch, cocos2d::Event* event) {//Don't implement this, or don't subclass at all and you get a fine ScrollView, albeit dead to other events.
CCLOG("MyListV::onTouchBegan");
return false; // HelloScene still gets the touch but only after this. This gets _all_ touches, everywhere, even outside this Node's bounds.
So next I try always returning true from my ScrollView
bool MyListV::onTouchBegan(cocos2d::Touch* touch, cocos2d::Event* event) {
CCLOG("MyListV::onTouchBegan");
return true; // HelloScene never gets any touches, not even to menu items
I don’t want HelloScene
to still respond to it’s many configuration buttons, apart from a small bar along the bottom of menu items. Besides, this has just broken ScrollView
's desired behaviour in that now the scroll position gets corrupted in some crazy way that slowly spreads.
Now I try and be selective and only let HelloScene
handle touches on its menu items (a small bar at the bottom, not the configuration options it generally presents).
bool MyListV::onTouchBegan(cocos2d::Touch* touch, cocos2d::Event* event) {
CCLOG("MyListV::onTouchBegan");
if (touch->getLocation().y < _position.y) return false;
return true;
That has the intended consequence but the ScrollView
class is still breaking.
So perhaps I can be more selective with when I allow my event to be consumed (i.e. when I return true
).
bool MyListV::onTouchBegan(cocos2d::Touch* touch, cocos2d::Event* event) {
CCLOG("WListV::onTouchBegan");
bool answer = ScrollView::onTouchBegan(touch, event);
CCLOG("%s", answer?"true":"false");
return answer;
But that is just futile, I may as well not override in the first place. HelloScene
is still getting events it never should which must be headed off in its handler with a simple binary flag to implement dialog modality. At least now I can sniff touch locations out here in the ScrollView
and respond accordingly.