allow finding the rootTag of any reactTag inside UIManager

Summary: added API to in UIManager to find the rootTag/View of any reactTag based on its layout (shadow views) hierarchy (not to be used by JS)

Reviewed By: javache

Differential Revision: D3750410

fbshipit-source-id: 68611e39930d53ece478f25245ddc7f7838daaa6
This commit is contained in:
Kevin Gozali
2016-08-28 22:46:42 -07:00
committed by Facebook Github Bot 9
parent 6729df3f28
commit 35e7a266db
4 changed files with 92 additions and 1 deletions

View File

@@ -90,6 +90,17 @@ RCT_EXTERN NSString *const RCTUIManagerRootViewKey;
*/
- (void)addUIBlock:(RCTViewManagerUIBlock)block;
/**
* Given a reactTag from a component, find its root view, if possible.
* Otherwise, this will give back nil.
*
* @param reactTag the component tag
* @param completion the completion block that will hand over the rootView, if any.
*
* @return the rootView
*/
- (void)rootViewForReactTag:(NSNumber *)reactTag withCompletion:(void (^)(UIView *view))completion;
/**
* The view that is currently first responder, according to the JS context.
*/

View File

@@ -1549,6 +1549,54 @@ RCT_EXPORT_METHOD(configureNextLayoutAnimation:(NSDictionary *)config
}];
}
- (void)rootViewForReactTag:(NSNumber *)reactTag withCompletion:(void (^)(UIView *view))completion
{
RCTAssertMainQueue();
RCTAssert(completion != nil, @"Attempted to resolve rootView for tag %@ without a completion block", reactTag);
if (reactTag == nil) {
completion(nil);
return;
}
dispatch_async(RCTGetUIManagerQueue(), ^{
NSNumber *rootTag = [self _rootTagForReactTag:reactTag];
dispatch_async(dispatch_get_main_queue(), ^{
UIView *rootView = nil;
if (rootTag != nil) {
rootView = [self viewForReactTag:rootTag];
}
completion(rootView);
});
});
}
- (NSNumber *)_rootTagForReactTag:(NSNumber *)reactTag
{
RCTAssert(!RCTIsMainQueue(), @"Should be called on shadow queue");
if (reactTag == nil) {
return nil;
}
if (RCTIsReactRootView(reactTag)) {
return reactTag;
}
NSNumber *rootTag = nil;
RCTShadowView *shadowView = _shadowViewRegistry[reactTag];
while (shadowView) {
RCTShadowView *parent = [shadowView reactSuperview];
if (!parent && RCTIsReactRootView(shadowView.reactTag)) {
rootTag = shadowView.reactTag;
break;
}
shadowView = parent;
}
return rootTag;
}
static UIView *_jsResponder;
+ (UIView *)JSResponder