mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-01-12 22:50:10 +08:00
Implement the nativeID functionality in a more efficient way (#23662)
Summary: Implement TODO, implement the nativeID functionality in a more efficient way instead of searching the whole view tree. [iOS] [Fixed] - Implement the nativeID functionality in a more efficient way Pull Request resolved: https://github.com/facebook/react-native/pull/23662 Differential Revision: D14323747 Pulled By: shergin fbshipit-source-id: 3d45dbf53ad2b6adb79b4331600d53b51ede76d4
This commit is contained in:
committed by
Facebook Github Bot
parent
50d095ce32
commit
b7b8836a7f
@@ -135,6 +135,14 @@ RCT_EXTERN NSString *const RCTUIManagerWillUpdateViewsDueToContentSizeMultiplier
|
||||
*/
|
||||
- (UIView *)viewForNativeID:(NSString *)nativeID withRootTag:(NSNumber *)rootTag;
|
||||
|
||||
/**
|
||||
* Register a view that is tagged with nativeID as its nativeID prop
|
||||
*
|
||||
* @param nativeID the id reference to native component relative to root view.
|
||||
* @param view the view that is tagged with nativeID as its nativeID prop.
|
||||
*/
|
||||
- (void)setNativeID:(NSString *)nativeID forView:(UIView *)view;
|
||||
|
||||
/**
|
||||
* The view that is currently first responder, according to the JS context.
|
||||
*/
|
||||
|
||||
@@ -50,6 +50,14 @@ static void RCTTraverseViewNodes(id<RCTComponent> view, void (^block)(id<RCTComp
|
||||
}
|
||||
}
|
||||
|
||||
static NSString *RCTNativeIDRegistryKey(NSString *nativeID, NSNumber *rootTag)
|
||||
{
|
||||
if (!nativeID || !rootTag) {
|
||||
return @"";
|
||||
}
|
||||
return [NSString stringWithFormat:@"%@-%@", rootTag, nativeID];
|
||||
}
|
||||
|
||||
NSString *const RCTUIManagerWillUpdateViewsDueToContentSizeMultiplierChangeNotification = @"RCTUIManagerWillUpdateViewsDueToContentSizeMultiplierChangeNotification";
|
||||
|
||||
@implementation RCTUIManager
|
||||
@@ -63,6 +71,7 @@ NSString *const RCTUIManagerWillUpdateViewsDueToContentSizeMultiplierChangeNotif
|
||||
|
||||
NSMutableDictionary<NSNumber *, RCTShadowView *> *_shadowViewRegistry; // RCT thread only
|
||||
NSMutableDictionary<NSNumber *, UIView *> *_viewRegistry; // Main thread only
|
||||
NSMapTable<NSString *, UIView *> *_nativeIDRegistry; // Main thread only
|
||||
|
||||
NSMapTable<RCTShadowView *, NSArray<NSString *> *> *_shadowViewsWithUpdatedProps; // UIManager queue only.
|
||||
NSHashTable<RCTShadowView *> *_shadowViewsWithUpdatedChildren; // UIManager queue only.
|
||||
@@ -106,6 +115,7 @@ RCT_EXPORT_MODULE()
|
||||
self->_rootViewTags = nil;
|
||||
self->_shadowViewRegistry = nil;
|
||||
self->_viewRegistry = nil;
|
||||
self->_nativeIDRegistry = nil;
|
||||
self->_bridge = nil;
|
||||
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
@@ -131,6 +141,15 @@ RCT_EXPORT_MODULE()
|
||||
return _viewRegistry;
|
||||
}
|
||||
|
||||
- (NSMapTable *)nativeIDRegistry
|
||||
{
|
||||
// Should be called on main queue
|
||||
if (!_nativeIDRegistry) {
|
||||
_nativeIDRegistry = [NSMapTable strongToWeakObjectsMapTable];
|
||||
}
|
||||
return _nativeIDRegistry;
|
||||
}
|
||||
|
||||
- (void)setBridge:(RCTBridge *)bridge
|
||||
{
|
||||
RCTAssert(_bridge == nil, @"Should not re-use same UIManager instance");
|
||||
@@ -138,6 +157,7 @@ RCT_EXPORT_MODULE()
|
||||
|
||||
_shadowViewRegistry = [NSMutableDictionary new];
|
||||
_viewRegistry = [NSMutableDictionary new];
|
||||
_nativeIDRegistry = [NSMapTable strongToWeakObjectsMapTable];
|
||||
|
||||
_shadowViewsWithUpdatedProps = [NSMapTable weakToStrongObjectsMapTable];
|
||||
_shadowViewsWithUpdatedChildren = [NSHashTable weakObjectsHashTable];
|
||||
@@ -366,31 +386,27 @@ static NSDictionary *deviceOrientationEventBody(UIDeviceOrientation orientation)
|
||||
} forTag:view.reactTag];
|
||||
}
|
||||
|
||||
/**
|
||||
* 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];
|
||||
if (!nativeID || !rootTag) {
|
||||
return nil;
|
||||
}
|
||||
return [_nativeIDRegistry objectForKey:RCTNativeIDRegistryKey(nativeID, rootTag)];
|
||||
}
|
||||
|
||||
- (UIView *)_lookupViewForNativeID:(NSString *)nativeID inView:(UIView *)view
|
||||
- (void)setNativeID:(NSString *)nativeID forView:(UIView *)view
|
||||
{
|
||||
RCTAssertMainQueue();
|
||||
if (view != nil && [nativeID isEqualToString:view.nativeID]) {
|
||||
return view;
|
||||
if (!nativeID) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (UIView *subview in view.subviews) {
|
||||
UIView *targetView = [self _lookupViewForNativeID:nativeID inView:subview];
|
||||
if (targetView != nil) {
|
||||
return targetView;
|
||||
__weak RCTUIManager *weakSelf = self;
|
||||
[self rootViewForReactTag:view.reactTag withCompletion:^(UIView *rootView) {
|
||||
if (rootView) {
|
||||
[weakSelf.nativeIDRegistry setObject:view forKey:RCTNativeIDRegistryKey(nativeID, rootView.reactTag)];
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)setSize:(CGSize)size forView:(UIView *)view
|
||||
|
||||
@@ -105,8 +105,6 @@ 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(accessibilityActions, reactAccessibilityElement.accessibilityActions, NSArray<NSString *>)
|
||||
@@ -171,6 +169,12 @@ RCT_CUSTOM_VIEW_PROPERTY(accessibilityStates, UIAccessibilityTraits, RCTView)
|
||||
view.reactAccessibilityElement.accessibilityTraits = (view.reactAccessibilityElement.accessibilityTraits & ~AccessibilityStatesMask) | maskedTraits;
|
||||
}
|
||||
|
||||
RCT_CUSTOM_VIEW_PROPERTY(nativeID, NSString *, RCTView)
|
||||
{
|
||||
view.nativeID = json ? [RCTConvert NSString:json] : defaultView.nativeID;
|
||||
[_bridge.uiManager setNativeID:view.nativeID forView:view];
|
||||
}
|
||||
|
||||
RCT_CUSTOM_VIEW_PROPERTY(pointerEvents, RCTPointerEvents, RCTView)
|
||||
{
|
||||
if ([view respondsToSelector:@selector(setPointerEvents:)]) {
|
||||
|
||||
Reference in New Issue
Block a user