-
Notifications
You must be signed in to change notification settings - Fork 24.3k
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
[Touches] Let only the nearest ancestor root view process touches #1372
Conversation
@tadeuzagallo, @nicklockwood: what do you think about this? |
What's the use case for nested root views? |
(Not that I need to know that in order to approve the PR - which seems reasonable to me). |
This is for the Exponent component that renders a React Native bundle inside of another React Native app ^_^ |
Any updates on this? |
What should we do with this? @ide @nicklockwood |
ping! |
cc: @majak, who has a better understanding of touch handling than I do. |
I believe this works. So I'm thinking about a bit more generic solution, which would expose I'm hesitant to merge this fix. The main reason being is it's not unreasonable to think you could want to do the opposite thing - make the embedded RN not receive any touches, and we already internally have have the UIScrollView embed need. @ide let me know what are your thoughts. |
@majak thanks for your analysis. I agree that this diff is too inflexible and it would be much better if the RN RootView provided a way for its superview to customize how touches within the RN RootView are handled. In our use case, we want to let a touch inside of a RootView get sent to the deepest subview that was directly touched (like the normal touch-handling behavior), and allow the touch to bubble up the view hierarchy. The superview of the RootView wants to intercept and create a copy of the touch with some properties changed, and let the new touch bubble up. This is a little diagram of what we're trying to do:
So an API that lets us write code that sits between the UIKit touch & gesture recognizer APIs and RN's touch handler would probably work for us. |
This is interesting. Just to double check, you want the inner root view to handle the touch, but at the same time the outer one should get some transformed touch as well? (No matter if the inner root view actually did anything with the touch.) |
@majak Yes, exactly. |
@ide This diff would be a part of the solution for your case? |
I think this diff would not be part of the solution since we want the touch to bubble up past the inner root view, but allow its superview to intercept the touch. The transformation of the UITouch would be just to change its |
@ide updated the pull request. |
So currently even the outer root view get touches with My guess is this is happening because of this: react-native/React/Base/RCTTouchHandler.m Lines 82 to 90 in 2e8eb65
I think you could try modify that logic to do continue climbing up the view hierarchy up even in case we found a react view, but its root view is not the same as the one the GR was set up on. |
@tadeuzagallo would you mind taking a look at this pull request? It's been a while since the last commit was reviewed. |
@ide Do you plan to continue working on this? Any opinions on the comment by majak? |
@mkonicek yep, I plan to look into this more eventually. Probably not super soon but I would like to build a solution! |
OK sounds good :) |
Just going through all old PRs. Based on the comments above leaving this one open. |
This is to support nested root views with independent bridges by preventing touches in the inner root view from being handled by the outer one. Previously, touches were handled by both touch handlers. This was problematic because the outer touch handler would dispatch a JS touch event to the outer bridge with a react tag from the inner root's descendant view. So if you touched view 7 in the inner root view, then view 7 in the outer root view would also receive a touch event. Instead, we want touches in the inner root view to stay in the inner root view. Performance-wise, I profiled this diff and didn't see an impact. On the start of each touch (when the finger goes down, not when it is dragged), the view hierarchy is traversed upwards until the first root view which is on the order of 10 property lookups for a typical view hierarchy. Test Plan: Tapped around in an inner root view and saw that components in the outer root view like text fields, etc were no longer receiving mystery touches.
I support the great cause of this pull request, but at this point it is kind of just a symbol of intending to do something about this that has just been a symbol for months. I think we should close it. If you want to start working on it again then that would be awesome! - and then I think just opening a new PR would be appropriate. |
* ignore version 0.11 * lint
This is to support nested root views with independent bridges by preventing touches in the inner root view from being handled by the outer one.
Previously, touches were handled by both touch handlers. This was problematic because the outer touch handler would dispatch a JS touch event to the outer bridge with a react tag from the inner root's descendant view. So if you touched view 7 in the inner root view, then view 7 in the outer root view would also receive a touch event. Instead, we want touches in the inner root view to stay in the inner root view.
Performance-wise, I profiled this diff and didn't see an impact. On the start of each touch (when the finger goes down, not when it is dragged), the view hierarchy is traversed upwards until the first root view which is on the order of 10 property lookups for a typical view hierarchy.
Test Plan: Tapped around in an inner root view and saw that components in the outer root view like text fields, etc were no longer receiving mystery touches.