New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tap events propagating when isPassThroughParentEnabled = false; #6606
Comments
|
@mukaschultze the default value of For example with the following setup: <StackLayout tap="onOuterStackTap">
<StackLayout tap="onStackTap" backgroundColor="red" height="200" isPassThroughParentEnabled="true">
<Button isUserInteractionEnabled="false" color="white" backgroundColor="green" tap="onTap" text="WILL NOT TAP"></Button>
<Button color="white" backgroundColor="blue" tap="onTap2" text="TAP"></Button>
</StackLayout>
</StackLayout>Tap on red should "fall through" to the outer stack (execute onOuterStackTap) Maybe the Label functionality you are looking for can be better implemented with |
|
@manoldonev, ok, still, the expected behavior is that if you remove or set to false the isPassthroughParentEnabled on the red StackLayout, the onOuterStackTap should not be fired, right? This is not what's happening With the code below the onOuterStackTap is still being called when tapping the red layout, in fact, both events are being called, so changing the isPassthroughParentEnabled of your example doesn't seem to change the behavior of taps at all. <StackLayout tap="onOuterStackTap">
<StackLayout tap="onStackTap" backgroundColor="red" height="200" isPassthroughParentEnabled="false">
<Button isUserInteractionEnabled="false" color="white" backgroundColor="green" tap="onTap" text="WILL NOT TAP"></Button>
<Button color="white" backgroundColor="blue" tap="onTap2" text="TAP"></Button>
</StackLayout>
</StackLayout> |
|
@mukaschultze just noticed that there is a typo in the code snippet I sent to you in my last reply -- property should be
If you set the property to true (see https://github.com/NativeScript/tns-core-modules-widgets/blob/2bdb7a42e23afe999ea4a56e736c3fd8d36a4bca/ios/TNSWidgets/TNSWidgets/UIView%2BPassthroughParent.m#L46) the red layout tap will not execute and the event will directly pass through to the outer wrapper. |
|
If you run the playground on Android and tap the Label (you can tap the StackLayout too, just tap around the button), you'll see that the tap is being triggered for the scrollview aswell. According to the docs:
So if we set it to true, the touch event should pass through the parent view if a child handled it. If we set it to false, the touch event should NOT pass through the parent if a child handled it. Currently, (at least on Android) if you tap anything, it'll call all the tap functions, regardless of this property. |
|
@edusperoni I'd like to clarify again that if the property is set to false, we are not tampering with the hit-testing logic specific to each platform in any way -- you can see the implementation here: NativeScript/tns-core-modules-widgets@5f34a58
This assumption is not correct. If you set the property to true, the touch event will only directly pass through to a parent view of the layout container in case an interactive child view of the layout container did not handle it -- you can find the original discussion that triggered the implementation of this feature here: #6191. I'll consider how to extend the property description as it seems it is kind of misleading at the moment. |
So maybe the problem isn't the |
|
@manoldonev @mukaschultze i think the change in behavior does not come from the pass through property but from the gesture handling system. in ns4 if you had a tap or swipe on a layout the gesture would not be recognized if triggered over a child. this was fixed in ns5. taps are gestures so , if I am correct, this is what your are seeing here. Btw false is the default behavior for pass through. the idea is actually contrary to what you are doing. the idea is to prevent views from catching touches event. used mostly for things like video overlays or map action overlays |
|
Hey @mukaschultze, I have just updated to NS5 and have this same annoying behaviour #3751, #4883. I think it makes perfect sense for children of a layout to intercept tap events, if the user taps within the hit area of the child. It also makes sense for the parent to respond to those tap events if the user taps outside its children, therefore in the hit area of the parent. This kind of nested hit areas is very common in UI design. On desktop frameworks such as Qt there is plenty freedom to either pass the event further up (or down in z order depending on how you look at it) to the parent or to accept the event by calling something like Anyway you can put a hack in to ignore the tap event. Implementation in TypeScript with Angular. declare private flag whether to ignore the tap and the corresponding getter and setter functions: then in ui template: As you can see when the child is tapped the ignoreTap flag is set to true. Then tap event on parent is also triggered, however at this point ignoreTap is queried. If ignoreTap has been set to true it is reset to false and the onParentTap is never called. On the other hand if ignoreTap is set to false, onParentTap is called. P.S. Thank you so much NativeScript for developing such an amazing product! |
|
In fact - I'm getting the parent callback first and then the child - even the work-around will not work for me. |
|
@gkoulin 's workaround along with setting isPassThroughParentEnabled to true should do the job, but since the parent tap is called before the child tap event, you will need to use nexttick function or something in the parent tap event to change that sequence. I have tested it and it works well. |
|
I actually found the source if the issue here. The reason is that when you dont set a touchListener on an android view, the view is effectively viewed as "pass through". This is a default android behavior: not clickable => default So the question is what do we want to do with this?
@rigor789 @NathanaelA @NathanWalker @edusperoni what s your view on this? i can easily create a PR once we decide what we prefer |
Environment
Describe the bug
Tap events are being propagated to parent objects, even when isPassThroughParentEnabled = false;
To Reproduce
Add nested tap events to the objects, a Label with a tap inside a StackLayout with another tap is enough, the StackLayout event will be fired even when the touch is on the Label.
Expected behavior
Taps not being propagated when isPassThroughParentEnabled is set to false.
Sample project
https://play.nativescript.org/?template=play-tsc&id=pj7FjN
Tap the label and see a log for each element.
Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.
The text was updated successfully, but these errors were encountered: