Implement nativeID prop to allow native code to reference react managed views in iOS

Reviewed By: javache

Differential Revision: D5228055

fbshipit-source-id: 8c934501d4ac946d80bf93d2ddb50f5fc38aea3c
This commit is contained in:
Yu Wang 2017-06-20 18:56:26 -07:00 committed by Facebook Github Bot
parent d217921b5e
commit 70e0455522
7 changed files with 54 additions and 3 deletions

View File

@ -218,8 +218,6 @@ module.exports = {
* Used to locate this view from native classes.
*
* > This disables the 'layout-only view removal' optimization for this view!
*
* @platform android
*/
nativeID: PropTypes.string,

View File

@ -179,7 +179,6 @@ const Text = React.createClass({
testID: PropTypes.string,
/**
* Used to locate this view from native code.
* @platform android
*/
nativeID: PropTypes.string,
/**

View File

@ -147,6 +147,16 @@ RCT_EXTERN NSString *const RCTUIManagerRootViewKey;
*/
- (void)rootViewForReactTag:(NSNumber *)reactTag withCompletion:(void (^)(UIView *view))completion;
/**
* Finds a view that is tagged with {@param nativeId} as its nativeID prop
* with the associated {@param rootTag} root tag view hierarchy. Returns the
* view if found, nil otherwise.
*
* @param nativeID the id reference to native component relative to root view.
* @param rootTag the react tag of root view hierarchy from which to find the view.
*/
- (UIView *)viewForNativeID:(NSString *)nativeID withRootTag:(NSNumber *)rootTag;
/**
* The view that is currently first responder, according to the JS context.
*/

View File

@ -433,6 +433,33 @@ BOOL RCTIsUIManagerQueue()
});
}
/**
* TODO(yuwang): implement the nativeID functionality in a more efficient way
* instead of searching the whole view tree
*/
- (UIView *)viewForNativeID:(NSString *)nativeID withRootTag:(NSNumber *)rootTag
{
RCTAssertMainQueue();
UIView *view = [self viewForReactTag:rootTag];
return [self _lookupViewForNativeID:nativeID inView:view];
}
- (UIView *)_lookupViewForNativeID:(NSString *)nativeID inView:(UIView *)view
{
RCTAssertMainQueue();
if (view != nil && [nativeID isEqualToString:view.nativeID]) {
return view;
}
for (UIView *subview in view.subviews) {
UIView *targetView = [self _lookupViewForNativeID:nativeID inView:subview];
if (targetView != nil) {
return targetView;
}
}
return nil;
}
- (void)setSize:(CGSize)size forView:(UIView *)view
{
RCTAssertMainQueue();

View File

@ -114,6 +114,8 @@ RCT_EXPORT_VIEW_PROPERTY(hasTVPreferredFocus, BOOL)
RCT_EXPORT_VIEW_PROPERTY(tvParallaxProperties, NSDictionary)
#endif
RCT_EXPORT_VIEW_PROPERTY(nativeID, NSString)
// Acessibility related properties
RCT_REMAP_VIEW_PROPERTY(accessible, reactAccessibilityElement.isAccessibilityElement, BOOL)
RCT_REMAP_VIEW_PROPERTY(accessibilityLabel, reactAccessibilityElement.accessibilityLabel, NSString)

View File

@ -24,6 +24,11 @@
- (void)insertReactSubview:(UIView *)subview atIndex:(NSInteger)atIndex NS_REQUIRES_SUPER;
- (void)removeReactSubview:(UIView *)subview NS_REQUIRES_SUPER;
/**
* The native id of the view, used to locate view from native codes
*/
@property (nonatomic, copy) NSString *nativeID;
/**
* Layout direction of the view.
* Internally backed to `semanticContentAttribute` property.

View File

@ -27,6 +27,16 @@
objc_setAssociatedObject(self, @selector(reactTag), reactTag, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSNumber *)nativeID
{
return objc_getAssociatedObject(self, _cmd);
}
- (void)setNativeID:(NSNumber *)nativeID
{
objc_setAssociatedObject(self, @selector(nativeID), nativeID, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
#if RCT_DEV
- (RCTShadowView *)_DEBUG_reactShadowView