From 47f18bdb175af5f76228b86b552e7bbe77db3667 Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Mon, 9 Jan 2017 00:09:38 -0800 Subject: [PATCH] Nobody outside RCTTouchHandler should treat it as UIGestureRecognizer subclass Reviewed By: mmmulani Differential Revision: D4387821 fbshipit-source-id: 8060772a5de669eeaca159ceac13b995d7518a1b --- React/Base/RCTRootView.m | 2 +- React/Base/RCTTouchHandler.h | 4 ++++ React/Base/RCTTouchHandler.m | 15 +++++++++++++++ React/Views/RCTModalHostView.m | 8 ++++---- React/Views/RCTModalHostViewManager.m | 1 - 5 files changed, 24 insertions(+), 6 deletions(-) diff --git a/React/Base/RCTRootView.m b/React/Base/RCTRootView.m index ebaad7ddc..41d155555 100644 --- a/React/Base/RCTRootView.m +++ b/React/Base/RCTRootView.m @@ -380,7 +380,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder) _bridge = bridge; self.reactTag = reactTag; _touchHandler = [[RCTTouchHandler alloc] initWithBridge:_bridge]; - [self addGestureRecognizer:_touchHandler]; + [_touchHandler attachToView:self]; [_bridge.uiManager registerRootView:self withSizeFlexibility:sizeFlexibility]; self.layer.backgroundColor = NULL; } diff --git a/React/Base/RCTTouchHandler.h b/React/Base/RCTTouchHandler.h index d5f4cbb4e..6f2df0444 100644 --- a/React/Base/RCTTouchHandler.h +++ b/React/Base/RCTTouchHandler.h @@ -16,6 +16,10 @@ @interface RCTTouchHandler : UIGestureRecognizer - (instancetype)initWithBridge:(RCTBridge *)bridge NS_DESIGNATED_INITIALIZER; + +- (void)attachToView:(UIView *)view; +- (void)detachFromView:(UIView *)view; + - (void)cancel; @end diff --git a/React/Base/RCTTouchHandler.m b/React/Base/RCTTouchHandler.m index 1c36073f8..b4d1d24ea 100644 --- a/React/Base/RCTTouchHandler.m +++ b/React/Base/RCTTouchHandler.m @@ -64,6 +64,21 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithTarget:(id)target action:(SEL)action) +- (void)attachToView:(UIView *)view +{ + RCTAssert(self.view == nil, @"RCTTouchHandler already has attached view."); + + [view addGestureRecognizer:self]; +} + +- (void)detachFromView:(UIView *)view +{ + RCTAssertParam(view); + RCTAssert(self.view == view, @"RCTTouchHandler attached to another view."); + + [view removeGestureRecognizer:self]; +} + typedef NS_ENUM(NSInteger, RCTTouchEventType) { RCTTouchEventTypeStart, RCTTouchEventTypeMove, diff --git a/React/Views/RCTModalHostView.m b/React/Views/RCTModalHostView.m index e41618161..adc776258 100644 --- a/React/Views/RCTModalHostView.m +++ b/React/Views/RCTModalHostView.m @@ -9,6 +9,8 @@ #import "RCTModalHostView.h" +#import + #import "RCTAssert.h" #import "RCTBridge.h" #import "RCTModalHostViewController.h" @@ -16,8 +18,6 @@ #import "RCTUIManager.h" #import "UIView+React.h" -#import - @implementation RCTModalHostView { __weak RCTBridge *_bridge; @@ -87,7 +87,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:coder) { RCTAssert(_reactSubview == nil, @"Modal view can only have one subview"); [super insertReactSubview:subview atIndex:atIndex]; - [subview addGestureRecognizer:_touchHandler]; + [_touchHandler attachToView:subview]; subview.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; @@ -99,7 +99,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:coder) { RCTAssert(subview == _reactSubview, @"Cannot remove view other than modal view"); [super removeReactSubview:subview]; - [subview removeGestureRecognizer:_touchHandler]; + [_touchHandler detachFromView:subview]; _reactSubview = nil; } diff --git a/React/Views/RCTModalHostViewManager.m b/React/Views/RCTModalHostViewManager.m index b228e0bde..8f99b5c73 100644 --- a/React/Views/RCTModalHostViewManager.m +++ b/React/Views/RCTModalHostViewManager.m @@ -12,7 +12,6 @@ #import "RCTBridge.h" #import "RCTModalHostView.h" #import "RCTModalHostViewController.h" -#import "RCTTouchHandler.h" #import "RCTShadowView.h" #import "RCTUtils.h"