From fbfce92e97fdfa2176ff82afb6a51f77fd0ed196 Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Thu, 31 Oct 2019 14:39:41 -0700 Subject: [PATCH] Use ReactTag to map events to component view Summary: Use `reactTag` instead of address of `UIView` to map events from paper components to Fabric. changelog: [internal] Reviewed By: shergin Differential Revision: D17954974 fbshipit-source-id: 0d8bf748e58f4cb6769e107bc7fd0e66b93d8f12 --- ...CTLegacyViewManagerInteropComponentView.mm | 27 +++++++++++++------ React/Views/RCTComponentData.h | 2 +- React/Views/RCTComponentData.m | 2 +- .../RCTLegacyViewManagerInteropCoordinator.h | 6 ++++- .../RCTLegacyViewManagerInteropCoordinator.mm | 23 ++++++++++------ 5 files changed, 41 insertions(+), 19 deletions(-) diff --git a/React/Fabric/Mounting/ComponentViews/LegacyViewManagerInterop/RCTLegacyViewManagerInteropComponentView.mm b/React/Fabric/Mounting/ComponentViews/LegacyViewManagerInterop/RCTLegacyViewManagerInteropComponentView.mm index fa27cc4a2a8..e03cd552627 100644 --- a/React/Fabric/Mounting/ComponentViews/LegacyViewManagerInterop/RCTLegacyViewManagerInteropComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/LegacyViewManagerInterop/RCTLegacyViewManagerInteropComponentView.mm @@ -34,6 +34,12 @@ using namespace facebook::react; return self; } +- (void)setTag:(NSInteger)tag +{ + [self.coordinator removeObserveForTag:self.tag]; + [super setTag:tag]; +} + + (NSMutableSet *)supportedViewManagers { static NSMutableSet *supported = @@ -106,14 +112,19 @@ using namespace facebook::react; if (!_paperView) { __weak __typeof(self) weakSelf = self; - _paperView = [self.coordinator viewWithInterceptor:^(std::string eventName, folly::dynamic event) { - if (weakSelf) { - __typeof(self) strongSelf = weakSelf; - auto eventEmitter = - std::static_pointer_cast(strongSelf->_eventEmitter); - eventEmitter->dispatchEvent(eventName, event); - } - }]; + _paperView = self.coordinator.paperView; + [self.coordinator addObserveForTag:self.tag + usingBlock:^(std::string eventName, folly::dynamic event) { + if (weakSelf) { + __typeof(self) strongSelf = weakSelf; + auto eventEmitter = + std::static_pointer_cast( + strongSelf->_eventEmitter); + eventEmitter->dispatchEvent(eventName, event); + } + }]; + + _paperView.reactTag = [NSNumber numberWithInteger:self.tag]; self.contentView = _paperView; } diff --git a/React/Views/RCTComponentData.h b/React/Views/RCTComponentData.h index 836f0eca1e6..9bd347a1bab 100644 --- a/React/Views/RCTComponentData.h +++ b/React/Views/RCTComponentData.h @@ -29,7 +29,7 @@ - (void)setProps:(NSDictionary *)props forView:(id)view; - (void)setProps:(NSDictionary *)props forShadowView:(RCTShadowView *)shadowView; -@property (nonatomic, copy, nullable) void (^eventInterceptor)(NSString *eventName, NSDictionary *event, id sender); +@property (nonatomic, copy, nullable) void (^eventInterceptor)(NSString *eventName, NSDictionary *event, NSNumber *reactTag); - (NSDictionary *)viewConfig; diff --git a/React/Views/RCTComponentData.m b/React/Views/RCTComponentData.m index 74d368d86df..df370f70a4c 100644 --- a/React/Views/RCTComponentData.m +++ b/React/Views/RCTComponentData.m @@ -117,7 +117,7 @@ static RCTPropBlock createEventSetter(NSString *propName, SEL setter,Interceptor } if (eventInterceptor) { - eventInterceptor(propName, event, strongTarget); + eventInterceptor(propName, event, strongTarget.reactTag); } else { RCTComponentEvent *componentEvent = [[RCTComponentEvent alloc] initWithName:propName viewTag:strongTarget.reactTag diff --git a/ReactCommon/fabric/components/legacyviewmanagerinterop/RCTLegacyViewManagerInteropCoordinator.h b/ReactCommon/fabric/components/legacyviewmanagerinterop/RCTLegacyViewManagerInteropCoordinator.h index 93463d30a83..a34c68c7033 100644 --- a/ReactCommon/fabric/components/legacyviewmanagerinterop/RCTLegacyViewManagerInteropCoordinator.h +++ b/ReactCommon/fabric/components/legacyviewmanagerinterop/RCTLegacyViewManagerInteropCoordinator.h @@ -19,7 +19,11 @@ typedef void (^InterceptorBlock)(std::string eventName, folly::dynamic event); - (instancetype)initWithComponentData:(RCTComponentData *)componentData; -- (UIView *)viewWithInterceptor:(InterceptorBlock)block; +- (UIView *)paperView; + +- (void)addObserveForTag:(NSInteger)tag usingBlock:(InterceptorBlock)block; + +- (void)removeObserveForTag:(NSInteger)tag; - (void)setProps:(folly::dynamic const &)props forView:(UIView *)view; diff --git a/ReactCommon/fabric/components/legacyviewmanagerinterop/RCTLegacyViewManagerInteropCoordinator.mm b/ReactCommon/fabric/components/legacyviewmanagerinterop/RCTLegacyViewManagerInteropCoordinator.mm index d1aac9aa723..944ef233ed4 100644 --- a/ReactCommon/fabric/components/legacyviewmanagerinterop/RCTLegacyViewManagerInteropCoordinator.mm +++ b/ReactCommon/fabric/components/legacyviewmanagerinterop/RCTLegacyViewManagerInteropCoordinator.mm @@ -19,7 +19,7 @@ using namespace facebook::react; Each instnace of `RCTLegacyViewManagerInteropComponentView` registers a block to which events are dispatched. This is the container that maps unretained UIView pointer to a block to which the event is dispatched. */ - NSMutableDictionary *_eventInterceptors; + NSMutableDictionary *_eventInterceptors; } - (instancetype)initWithComponentData:(RCTComponentData *)componentData; @@ -30,10 +30,9 @@ using namespace facebook::react; _eventInterceptors = [NSMutableDictionary new]; __weak __typeof(self) weakSelf = self; - _componentData.eventInterceptor = ^(NSString *eventName, NSDictionary *event, id sender) { + _componentData.eventInterceptor = ^(NSString *eventName, NSDictionary *event, NSNumber *reactTag) { __typeof(self) strongSelf = weakSelf; - InterceptorBlock block = - [strongSelf->_eventInterceptors objectForKey:[NSValue valueWithNonretainedObject:sender]]; + InterceptorBlock block = [strongSelf->_eventInterceptors objectForKey:reactTag]; if (block) { block(std::string([RCTNormalizeInputEventName(eventName) UTF8String]), convertIdToFollyDynamic(event)); } @@ -42,11 +41,19 @@ using namespace facebook::react; return self; } -- (UIView *)viewWithInterceptor:(InterceptorBlock)block +- (void)addObserveForTag:(NSInteger)tag usingBlock:(InterceptorBlock)block { - UIView *view = [_componentData createViewWithTag:NULL]; - [_eventInterceptors setObject:block forKey:[NSValue valueWithNonretainedObject:view]]; - return view; + [_eventInterceptors setObject:block forKey:[NSNumber numberWithInteger:tag]]; +} + +- (void)removeObserveForTag:(NSInteger)tag +{ + [_eventInterceptors removeObjectForKey:[NSNumber numberWithInteger:tag]]; +} + +- (UIView *)paperView +{ + return [_componentData createViewWithTag:NULL]; } - (void)setProps:(folly::dynamic const &)props forView:(UIView *)view