-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Fix onPress handlers on nested Text components #560
Conversation
@rigdern I would definitely like to avoid seeing a specific reference to RichTextBlock (or any specific view type) inside TouchHandler as well, and yeah, I can see where you would have wanted to follow the pattern in ReactAndroid with the ReactCompoundView (https://github.com/facebook/react-native/blob/c91591b98792ffbd0826a4bda7304d63a52f0479/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactCompoundView.java#L19), but cannot do this due to sealed framework elements. I can think of two things to avoid having view-specific code in the TouchHandler:
Honestly, I was hoping to get rid of the DependencyObjectExtensions all together at some point, but I don't see many other options because so many of the XAML elements are sealed. Maybe there are other options, but can't think of any right now. Update: I forgot that the pointerEvents logic was already put in the ConditionalWeakTable in DependencyObjectExtensions, so touch-related behavior is already being done in this way... |
Does (1) concern you from a performance perspective? Apps can have lots of text views so we'd end up adding a bunch of extra UserControls or Canvases. Can you elaborate on (2)? Are you imagining something like the following? Add a method called Did you have any thoughts on the idea of putting the |
Yes, there is definitely a perf concern for 1). I would take an object-oriented approach for 2), creating an interface like ReactCompoundView, and associating React view instances with instances of the interface. I think it would not be a good idea for now to give other components full access to view managers, feels like too much breaking of encapsulation. |
d05b27b
to
2418549
Compare
I pushed an implementation of (2). I thought a little bit about a replacement for the DependencyObjectExtensions file. If you need this technique to work on non- |
Agreed, would save us a couple allocations and taking the lock in CWT. In fact, it used to be that way before we introduced DependencyObect as the base class. I removed it because I wasn't sure if a case could be made where a user implementation of a view manager would want to use the Tag property, but its okay with me if you want to add it back. From: Adam Comellamailto:notifications@github.com I pushed an implementation of (2). I thought a little bit about a replacement for the DependencyObjectExtensions file. If you need this technique to work on non- You are receiving this because you commented. |
I'm happy enough with the approach I submitted in this PR and I don't want to do the refactoring now. We can keep it in mind for later. |
@@ -97,6 +98,32 @@ internal static ThemedReactContext GetReactContext(this DependencyObject view) | |||
return elementData.Context; | |||
} | |||
|
|||
internal static void SetReactCompoundView(this DependencyObject view, IReactCompoundView compoundView) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're probably going to want to make this public.
Currently, onPress handlers only work on outermost Text components. This change enables you to place onPress handlers on nested Text components. For example, this now works: <Text> <Text onPress={this._handlePress}>Press Me</Text> </Text> In the fix, we need to manually do hit testing on outermost Text components to see if any of the nested Text components got hit. This is because the nested Text components are represented by Inlines rather than by UIElements.
2418549
to
036ea81
Compare
Currently, onPress handlers only work on outermost Text components. This change enables you to place onPress handlers on nested Text components. For example, this now works: <Text> <Text onPress={this._handlePress}>Press Me</Text> </Text> In the fix, we need to manually do hit testing on outermost Text components to see if any of the nested Text components got hit. This is because the nested Text components are represented by Inlines rather than by UIElements.
Currently, onPress handlers only work on outermost Text components. This change enables you to place onPress handlers on nested Text components. For example, this now works: <Text> <Text onPress={this._handlePress}>Press Me</Text> </Text> In the fix, we need to manually do hit testing on outermost Text components to see if any of the nested Text components got hit. This is because the nested Text components are represented by Inlines rather than by UIElements.
Notes
I would have preferred to make
GetReactTagAtPoint
a polymorphic method so that the code that authors the Text component could also provide an implementation forGetReactTagAtPoint
. However, because we don't control the source code forRichTextBlock
and it's sealed, I couldn't find a way to do this.Perhaps you know of a way?
One other option would be to make
GetReactTagAtPoint
a method of the view manager andTouchHandler
would have to somehow find the view manager for the view and invoke the method.Commit Message
Currently, onPress handlers only work on outermost Text components.
This change enables you to place onPress handlers on nested Text
components. For example, this now works:
In the fix, we need to manually do hit testing on outermost Text
components to see if any of the nested Text components got hit. This is
because the nested Text components are represented by Inlines rather than
by UIElements.