diff --git a/ReactWindows/ReactNative/ReactNative.csproj b/ReactWindows/ReactNative/ReactNative.csproj
index 45dc1dbee9f..f1fc0501fe5 100644
--- a/ReactWindows/ReactNative/ReactNative.csproj
+++ b/ReactWindows/ReactNative/ReactNative.csproj
@@ -272,7 +272,9 @@
+
+
@@ -362,6 +364,7 @@
+
diff --git a/ReactWindows/ReactNative/Touch/TouchHandler.cs b/ReactWindows/ReactNative/Touch/TouchHandler.cs
index 77227e2d2f4..e347e885fe7 100644
--- a/ReactWindows/ReactNative/Touch/TouchHandler.cs
+++ b/ReactWindows/ReactNative/Touch/TouchHandler.cs
@@ -46,10 +46,13 @@ private void OnPointerPressed(object sender, PointerRoutedEventArgs e)
}
var reactView = GetReactViewFromView(e.OriginalSource as UIElement);
+ var reactTag = reactView.GetReactCompoundView().GetReactTagAtPoint(reactView,
+ e.GetCurrentPoint(reactView).Position);
+
if (reactView != null && _view.CapturePointer(e.Pointer))
{
var pointer = new ReactPointer();
- pointer.Target = reactView.GetTag();
+ pointer.Target = reactTag;
pointer.PointerId = e.Pointer.PointerId;
pointer.Identifier = ++_pointerIDs;
pointer.ReactView = reactView;
diff --git a/ReactWindows/ReactNative/UIManager/DependencyObjectExtensions.cs b/ReactWindows/ReactNative/UIManager/DependencyObjectExtensions.cs
index 7bbd14b8494..8ace3fe8997 100644
--- a/ReactWindows/ReactNative/UIManager/DependencyObjectExtensions.cs
+++ b/ReactWindows/ReactNative/UIManager/DependencyObjectExtensions.cs
@@ -11,6 +11,7 @@ public static class DependencyObjectExtensions
{
private static readonly ConditionalWeakTable s_properties =
new ConditionalWeakTable();
+ private static readonly IReactCompoundView s_defaultCompoundView = new ReactDefaultCompoundView();
///
/// Sets the pointer events for the view.
@@ -44,6 +45,46 @@ public static PointerEvents GetPointerEvents(this DependencyObject view)
return elementData.PointerEvents.Value;
}
+ ///
+ /// Associates an implementation of IReactCompoundView with the view.
+ ///
+ /// The view.
+ /// The implementation of IReactCompoundView.
+ public static void SetReactCompoundView(this DependencyObject view, IReactCompoundView compoundView)
+ {
+ if (view == null)
+ throw new ArgumentNullException(nameof(view));
+
+ s_properties.GetOrCreateValue(view).CompoundView = compoundView;
+ }
+
+ ///
+ /// Gets the implementation of IReactCompoundView associated with the view.
+ ///
+ /// The view.
+ ///
+ /// The implementation of IReactCompoundView associated with the view. Defaults to
+ /// an instance of ReactDefaultCompoundView when no other implementation has been
+ /// provided.
+ ///
+ public static IReactCompoundView GetReactCompoundView(this DependencyObject view)
+ {
+ if (view == null)
+ throw new ArgumentNullException(nameof(view));
+
+ var elementData = default(DependencyObjectData);
+ if (s_properties.TryGetValue(view, out elementData))
+ {
+ var compoundView = elementData.CompoundView;
+ if (compoundView != null)
+ {
+ return compoundView;
+ }
+ }
+
+ return s_defaultCompoundView;
+ }
+
internal static void SetTag(this DependencyObject view, int tag)
{
if (view == null)
@@ -115,6 +156,8 @@ class DependencyObjectData
public PointerEvents? PointerEvents { get; set; }
public int? Tag { get; set; }
+
+ public IReactCompoundView CompoundView { get; set; }
}
}
}
diff --git a/ReactWindows/ReactNative/UIManager/IReactCompoundView.cs b/ReactWindows/ReactNative/UIManager/IReactCompoundView.cs
new file mode 100644
index 00000000000..7c97ff99731
--- /dev/null
+++ b/ReactWindows/ReactNative/UIManager/IReactCompoundView.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Windows.Foundation;
+using Windows.UI.Xaml;
+
+namespace ReactNative.UIManager
+{
+ ///
+ /// Interface consisting of methods which are relevant to views which contain
+ /// visuals that have react tags but are not rendered using UIElements.
+ ///
+ public interface IReactCompoundView
+ {
+ ///
+ /// Returns the react tag rendered at point in reactView. The view
+ /// is not expected to do hit testing on its UIElement descendants. Rather,
+ /// this is useful for views which are composed of visuals that are associated
+ /// with react tags but the visuals are not UIElements.
+ ///
+ /// The react view to do hit testing within.
+ /// The point to hit test in coordinates that are relative to the view.
+ /// The react tag rendered at point in reactView.
+ int GetReactTagAtPoint(UIElement reactView, Point point);
+ }
+}
diff --git a/ReactWindows/ReactNative/UIManager/ReactDefaultCompoundView.cs b/ReactWindows/ReactNative/UIManager/ReactDefaultCompoundView.cs
new file mode 100644
index 00000000000..25daaddb1e4
--- /dev/null
+++ b/ReactWindows/ReactNative/UIManager/ReactDefaultCompoundView.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Windows.Foundation;
+using Windows.UI.Xaml;
+
+namespace ReactNative.UIManager
+{
+ class ReactDefaultCompoundView : IReactCompoundView
+ {
+ public int GetReactTagAtPoint(UIElement reactView, Point point)
+ {
+ return reactView.GetTag();
+ }
+ }
+}
diff --git a/ReactWindows/ReactNative/Views/Text/ReactTextCompoundView.cs b/ReactWindows/ReactNative/Views/Text/ReactTextCompoundView.cs
new file mode 100644
index 00000000000..58c65f1edcf
--- /dev/null
+++ b/ReactWindows/ReactNative/Views/Text/ReactTextCompoundView.cs
@@ -0,0 +1,22 @@
+using ReactNative.UIManager;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Windows.Foundation;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+
+namespace ReactNative.Views.Text
+{
+ class ReactTextCompoundView : IReactCompoundView
+ {
+ public int GetReactTagAtPoint(UIElement reactView, Point point)
+ {
+ var richTextBlock = reactView.As();
+ var textPointer = richTextBlock.GetPositionFromPoint(point);
+ return textPointer.Parent.GetTag();
+ }
+ }
+}
diff --git a/ReactWindows/ReactNative/Views/Text/ReactTextViewManager.cs b/ReactWindows/ReactNative/Views/Text/ReactTextViewManager.cs
index e5755c165b1..a46ee3ef435 100644
--- a/ReactWindows/ReactNative/Views/Text/ReactTextViewManager.cs
+++ b/ReactWindows/ReactNative/Views/Text/ReactTextViewManager.cs
@@ -13,6 +13,7 @@ namespace ReactNative.Views.Text
///
public class ReactTextViewManager : ViewParentManager
{
+ private static readonly IReactCompoundView s_compoundView = new ReactTextCompoundView();
private const double DefaultFontSize = 15;
///
@@ -162,6 +163,7 @@ protected override RichTextBlock CreateViewInstance(ThemedReactContext reactCont
};
richTextBlock.Blocks.Add(new Paragraph());
+ richTextBlock.SetReactCompoundView(s_compoundView);
return richTextBlock;
}