From 1807c5b48d7b72e4f171dc105db6eff6291614e5 Mon Sep 17 00:00:00 2001 From: Yogev Ben David Date: Wed, 27 Nov 2019 17:00:20 +0200 Subject: [PATCH] Prevent creation of button react view with the same componentId (#5687) When updating buttons with mergeOptions, existing custom buttons are unmounted and then recreated. This commit adds an optimisation which prevents the react components from being recreated. To avoid unnecessary recreation, add an `id` to the component. If an existing react view is found for that id, it will be reused. --- lib/ios/NSArray+utils.h | 11 + lib/ios/NSArray+utils.m | 31 ++ lib/ios/RNNNavigationButtons.m | 288 +++++++++--------- lib/ios/RNNReactComponentRegistry.m | 14 +- lib/ios/RNNUIBarButtonItem.h | 2 +- lib/ios/RNNUIBarButtonItem.m | 20 +- .../project.pbxproj | 8 + 7 files changed, 214 insertions(+), 160 deletions(-) create mode 100644 lib/ios/NSArray+utils.h create mode 100644 lib/ios/NSArray+utils.m diff --git a/lib/ios/NSArray+utils.h b/lib/ios/NSArray+utils.h new file mode 100644 index 00000000000..4cbb168065b --- /dev/null +++ b/lib/ios/NSArray+utils.h @@ -0,0 +1,11 @@ +#import + +@interface NSArray (utils) + +- (NSArray *)intersect:(NSArray *)array withPropertyName:(NSString *)propertyName; + +- (NSArray *)difference:(NSArray *)array withPropertyName:(NSString *)propertyName; + +- (NSArray *)mapObjectsUsingBlock:(id (^)(id obj, NSUInteger idx))block; + +@end diff --git a/lib/ios/NSArray+utils.m b/lib/ios/NSArray+utils.m new file mode 100644 index 00000000000..24131f25cdd --- /dev/null +++ b/lib/ios/NSArray+utils.m @@ -0,0 +1,31 @@ +#import "NSArray+utils.h" + +@implementation NSArray (utils) + +- (NSArray *)intersect:(NSArray *)array withPropertyName:(NSString *)propertyName { + NSMutableArray* intersection = [NSMutableArray new]; + for (NSObject* object in array) { + NSArray* filteredArray = [self filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"%@ == %@", propertyName, object]]; + [intersection addObjectsFromArray:filteredArray]; + } + + return [NSArray arrayWithArray:intersection]; +} + +- (NSArray *)difference:(NSArray *)array withPropertyName:(NSString *)propertyName { + NSMutableArray* diff = [NSMutableArray arrayWithArray:self]; + NSArray* intersection = [self intersect:array withPropertyName:propertyName]; + [diff removeObjectsInArray:intersection]; + + return [NSArray arrayWithArray:diff]; +} + +- (NSArray *)mapObjectsUsingBlock:(id (^)(id obj, NSUInteger idx))block { + NSMutableArray *result = [NSMutableArray arrayWithCapacity:[self count]]; + [self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + [result addObject:block(obj, idx)]; + }]; + return result; +} + +@end diff --git a/lib/ios/RNNNavigationButtons.m b/lib/ios/RNNNavigationButtons.m index de9084e9b0c..0f0e3396fe5 100644 --- a/lib/ios/RNNNavigationButtons.m +++ b/lib/ios/RNNNavigationButtons.m @@ -7,6 +7,7 @@ #import "UIImage+insets.h" #import "UIViewController+LayoutProtocol.h" #import "RNNFontAttributesCreator.h" +#import "NSArray+utils.h" @interface RNNNavigationButtons() @@ -19,167 +20,180 @@ @interface RNNNavigationButtons() @implementation RNNNavigationButtons -(instancetype)initWithViewController:(UIViewController*)viewController componentRegistry:(id)componentRegistry { - self = [super init]; - - self.viewController = viewController; - self.componentRegistry = componentRegistry; - - return self; + self = [super init]; + + self.viewController = viewController; + self.componentRegistry = componentRegistry; + + return self; } - (void)applyLeftButtons:(NSArray *)leftButtons rightButtons:(NSArray *)rightButtons defaultLeftButtonStyle:(RNNButtonOptions *)defaultLeftButtonStyle defaultRightButtonStyle:(RNNButtonOptions *)defaultRightButtonStyle { - _defaultLeftButtonStyle = defaultLeftButtonStyle; - _defaultRightButtonStyle = defaultRightButtonStyle; - if (leftButtons) { - [self setButtons:leftButtons side:@"left" animated:NO defaultStyle:_defaultLeftButtonStyle insets:[self leftButtonInsets:_defaultLeftButtonStyle.iconInsets]]; - } - - if (rightButtons) { - [self setButtons:rightButtons side:@"right" animated:NO defaultStyle:_defaultRightButtonStyle insets:[self rightButtonInsets:_defaultRightButtonStyle.iconInsets]]; - } + _defaultLeftButtonStyle = defaultLeftButtonStyle; + _defaultRightButtonStyle = defaultRightButtonStyle; + if (leftButtons) { + [self setButtons:leftButtons side:@"left" animated:NO defaultStyle:_defaultLeftButtonStyle insets:[self leftButtonInsets:_defaultLeftButtonStyle.iconInsets]]; + } + + if (rightButtons) { + [self setButtons:rightButtons side:@"right" animated:NO defaultStyle:_defaultRightButtonStyle insets:[self rightButtonInsets:_defaultRightButtonStyle.iconInsets]]; + } } -(void)setButtons:(NSArray*)buttons side:(NSString*)side animated:(BOOL)animated defaultStyle:(RNNButtonOptions *)defaultStyle insets:(UIEdgeInsets)insets { - NSMutableArray *barButtonItems = [NSMutableArray new]; - NSArray* resolvedButtons = [self resolveButtons:buttons]; - for (NSDictionary *button in resolvedButtons) { - RNNUIBarButtonItem* barButtonItem = [self buildButton:button defaultStyle:defaultStyle insets:insets]; - if(barButtonItem) { - [barButtonItems addObject:barButtonItem]; - } - UIColor* color = [self color:[RCTConvert UIColor:button[@"color"]] defaultColor:[defaultStyle.color getWithDefaultValue:nil]]; - if (color) { - self.viewController.navigationController.navigationBar.tintColor = color; - } - } - - if ([side isEqualToString:@"left"]) { - [self.viewController.navigationItem setLeftBarButtonItems:barButtonItems animated:animated]; - } - - if ([side isEqualToString:@"right"]) { - [self.viewController.navigationItem setRightBarButtonItems:barButtonItems animated:animated]; - } + NSMutableArray *barButtonItems = [NSMutableArray new]; + NSArray* resolvedButtons = [self resolveButtons:buttons]; + for (NSDictionary *button in resolvedButtons) { + RNNUIBarButtonItem* barButtonItem = [self buildButton:button defaultStyle:defaultStyle insets:insets]; + if(barButtonItem) { + [barButtonItems addObject:barButtonItem]; + } + UIColor* color = [self color:[RCTConvert UIColor:button[@"color"]] defaultColor:[defaultStyle.color getWithDefaultValue:nil]]; + if (color) { + self.viewController.navigationController.navigationBar.tintColor = color; + } + } + + if ([side isEqualToString:@"left"]) { + [self clearPreviousButtonViews:barButtonItems oldButtons:self.viewController.navigationItem.leftBarButtonItems]; + [self.viewController.navigationItem setLeftBarButtonItems:barButtonItems animated:animated]; + } + + if ([side isEqualToString:@"right"]) { + [self clearPreviousButtonViews:barButtonItems oldButtons:self.viewController.navigationItem.rightBarButtonItems]; + [self.viewController.navigationItem setRightBarButtonItems:barButtonItems animated:animated]; + } +} + +- (void)clearPreviousButtonViews:(NSArray *)newButtons oldButtons:(NSArray *)oldButtons { + NSArray* removedButtons = [oldButtons difference:newButtons withPropertyName:@"customView"]; + + for (UIBarButtonItem* buttonItem in removedButtons) { + RNNReactView* reactView = buttonItem.customView; + if ([reactView isKindOfClass:[RNNReactView class]]) { + [_componentRegistry removeChildComponent:reactView.componentId]; + } + } } - (NSArray *)resolveButtons:(id)buttons { - if ([buttons isKindOfClass:[NSArray class]]) { - return buttons; - } else { - return @[buttons]; - } + if ([buttons isKindOfClass:[NSArray class]]) { + return buttons; + } else { + return @[buttons]; + } } -(RNNUIBarButtonItem*)buildButton: (NSDictionary*)dictionary defaultStyle:(RNNButtonOptions *)defaultStyle insets:(UIEdgeInsets)insets { - NSString* buttonId = dictionary[@"id"]; - NSString* title = [self getValue:dictionary[@"text"] withDefault:[defaultStyle.text getWithDefaultValue:nil]]; - NSDictionary* component = dictionary[@"component"]; - NSString* systemItemName = dictionary[@"systemItem"]; - - UIColor* color = [self color:[RCTConvert UIColor:dictionary[@"color"]] defaultColor:[defaultStyle.color getWithDefaultValue:nil]]; - UIColor* disabledColor = [self color:[RCTConvert UIColor:dictionary[@"disabledColor"]] defaultColor:[defaultStyle.disabledColor getWithDefaultValue:nil]]; - - if (!buttonId) { - @throw [NSException exceptionWithName:@"NSInvalidArgumentException" reason:[@"button id is not specified " stringByAppendingString:title] userInfo:nil]; - } - - UIImage* defaultIcon = [defaultStyle.icon getWithDefaultValue:nil]; - UIImage* iconImage = [self getValue:dictionary[@"icon"] withDefault:defaultIcon]; - if (![iconImage isKindOfClass:[UIImage class]]) { - iconImage = [RCTConvert UIImage:iconImage]; - } - - if (iconImage) { - iconImage = [iconImage imageWithInsets:insets]; - if (color) { - iconImage = [iconImage withTintColor:color]; - } - } - - - RNNUIBarButtonItem *barButtonItem; - if (component) { - RNNComponentOptions* componentOptions = [RNNComponentOptions new]; - componentOptions.componentId = [[Text alloc] initWithValue:component[@"componentId"]]; - componentOptions.name = [[Text alloc] initWithValue:component[@"name"]]; - - RNNReactView *view = [_componentRegistry createComponentIfNotExists:componentOptions parentComponentId:self.viewController.layoutInfo.componentId reactViewReadyBlock:nil]; - barButtonItem = [[RNNUIBarButtonItem alloc] init:buttonId withCustomView:view componentRegistry:_componentRegistry]; - } else if (iconImage) { - barButtonItem = [[RNNUIBarButtonItem alloc] init:buttonId withIcon:iconImage]; - } else if (title) { - barButtonItem = [[RNNUIBarButtonItem alloc] init:buttonId withTitle:title]; - - NSMutableDictionary *buttonTextAttributes = [RCTHelpers textAttributesFromDictionary:dictionary withPrefix:@"button"]; - if (buttonTextAttributes.allKeys.count > 0) { - [barButtonItem setTitleTextAttributes:buttonTextAttributes forState:UIControlStateNormal]; - } - } else if (systemItemName) { - barButtonItem = [[RNNUIBarButtonItem alloc] init:buttonId withSystemItem:systemItemName]; - } else { - return nil; - } - - barButtonItem.target = self.viewController; - barButtonItem.action = @selector(onButtonPress:); - - NSNumber *enabled = [self getValue:dictionary[@"enabled"] withDefault:defaultStyle.enabled.getValue]; - BOOL enabledBool = enabled ? [enabled boolValue] : YES; - [barButtonItem setEnabled:enabledBool]; - - NSMutableDictionary* textAttributes = [NSMutableDictionary dictionaryWithDictionary:[RNNFontAttributesCreator createWithFontFamily:dictionary[@"fontFamily"] ?: [defaultStyle.fontFamily getWithDefaultValue:nil] fontSize:dictionary[@"fontSize"] defaultFontSize:[defaultStyle.fontSize getWithDefaultValue:@(17)] fontWeight:dictionary[@"fontWeight"] color:nil defaultColor:nil]]; - NSMutableDictionary* disabledTextAttributes = [NSMutableDictionary dictionaryWithDictionary:[RNNFontAttributesCreator createWithFontFamily:dictionary[@"fontFamily"] ?: [defaultStyle.fontFamily getWithDefaultValue:nil] fontSize:dictionary[@"fontSize"] defaultFontSize:[defaultStyle.fontSize getWithDefaultValue:@(17)] fontWeight:dictionary[@"fontWeight"] color:nil defaultColor:nil]]; - - if (!enabledBool && disabledColor) { - color = disabledColor; - [disabledTextAttributes setObject:disabledColor forKey:NSForegroundColorAttributeName]; - } - - if (color) { - [textAttributes setObject:color forKey:NSForegroundColorAttributeName]; - [barButtonItem setImage:[[iconImage withTintColor:color] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]]; - barButtonItem.tintColor = color; - } - - [barButtonItem setTitleTextAttributes:textAttributes forState:UIControlStateNormal]; - [barButtonItem setTitleTextAttributes:textAttributes forState:UIControlStateHighlighted]; - [barButtonItem setTitleTextAttributes:disabledTextAttributes forState:UIControlStateDisabled]; - - NSString *testID = dictionary[@"testID"]; - if (testID) - { - barButtonItem.accessibilityIdentifier = testID; - } - - return barButtonItem; + NSString* buttonId = dictionary[@"id"]; + NSString* title = [self getValue:dictionary[@"text"] withDefault:[defaultStyle.text getWithDefaultValue:nil]]; + NSDictionary* component = dictionary[@"component"]; + NSString* systemItemName = dictionary[@"systemItem"]; + + UIColor* color = [self color:[RCTConvert UIColor:dictionary[@"color"]] defaultColor:[defaultStyle.color getWithDefaultValue:nil]]; + UIColor* disabledColor = [self color:[RCTConvert UIColor:dictionary[@"disabledColor"]] defaultColor:[defaultStyle.disabledColor getWithDefaultValue:nil]]; + + if (!buttonId) { + @throw [NSException exceptionWithName:@"NSInvalidArgumentException" reason:[@"button id is not specified " stringByAppendingString:title] userInfo:nil]; + } + + UIImage* defaultIcon = [defaultStyle.icon getWithDefaultValue:nil]; + UIImage* iconImage = [self getValue:dictionary[@"icon"] withDefault:defaultIcon]; + if (![iconImage isKindOfClass:[UIImage class]]) { + iconImage = [RCTConvert UIImage:iconImage]; + } + + if (iconImage) { + iconImage = [iconImage imageWithInsets:insets]; + if (color) { + iconImage = [iconImage withTintColor:color]; + } + } + + + RNNUIBarButtonItem *barButtonItem; + if (component) { + RNNComponentOptions* componentOptions = [RNNComponentOptions new]; + componentOptions.componentId = [[Text alloc] initWithValue:component[@"componentId"]]; + componentOptions.name = [[Text alloc] initWithValue:component[@"name"]]; + + RNNReactView *view = [_componentRegistry createComponentIfNotExists:componentOptions parentComponentId:self.viewController.layoutInfo.componentId reactViewReadyBlock:nil]; + barButtonItem = [[RNNUIBarButtonItem alloc] init:buttonId withCustomView:view]; + } else if (iconImage) { + barButtonItem = [[RNNUIBarButtonItem alloc] init:buttonId withIcon:iconImage]; + } else if (title) { + barButtonItem = [[RNNUIBarButtonItem alloc] init:buttonId withTitle:title]; + + NSMutableDictionary *buttonTextAttributes = [RCTHelpers textAttributesFromDictionary:dictionary withPrefix:@"button"]; + if (buttonTextAttributes.allKeys.count > 0) { + [barButtonItem setTitleTextAttributes:buttonTextAttributes forState:UIControlStateNormal]; + } + } else if (systemItemName) { + barButtonItem = [[RNNUIBarButtonItem alloc] init:buttonId withSystemItem:systemItemName]; + } else { + return nil; + } + + barButtonItem.target = self.viewController; + barButtonItem.action = @selector(onButtonPress:); + + NSNumber *enabled = [self getValue:dictionary[@"enabled"] withDefault:defaultStyle.enabled.getValue]; + BOOL enabledBool = enabled ? [enabled boolValue] : YES; + [barButtonItem setEnabled:enabledBool]; + + NSMutableDictionary* textAttributes = [NSMutableDictionary dictionaryWithDictionary:[RNNFontAttributesCreator createWithFontFamily:dictionary[@"fontFamily"] ?: [defaultStyle.fontFamily getWithDefaultValue:nil] fontSize:dictionary[@"fontSize"] defaultFontSize:[defaultStyle.fontSize getWithDefaultValue:@(17)] fontWeight:dictionary[@"fontWeight"] color:nil defaultColor:nil]]; + NSMutableDictionary* disabledTextAttributes = [NSMutableDictionary dictionaryWithDictionary:[RNNFontAttributesCreator createWithFontFamily:dictionary[@"fontFamily"] ?: [defaultStyle.fontFamily getWithDefaultValue:nil] fontSize:dictionary[@"fontSize"] defaultFontSize:[defaultStyle.fontSize getWithDefaultValue:@(17)] fontWeight:dictionary[@"fontWeight"] color:nil defaultColor:nil]]; + + if (!enabledBool && disabledColor) { + color = disabledColor; + [disabledTextAttributes setObject:disabledColor forKey:NSForegroundColorAttributeName]; + } + + if (color) { + [textAttributes setObject:color forKey:NSForegroundColorAttributeName]; + [barButtonItem setImage:[[iconImage withTintColor:color] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]]; + barButtonItem.tintColor = color; + } + + [barButtonItem setTitleTextAttributes:textAttributes forState:UIControlStateNormal]; + [barButtonItem setTitleTextAttributes:textAttributes forState:UIControlStateHighlighted]; + [barButtonItem setTitleTextAttributes:disabledTextAttributes forState:UIControlStateDisabled]; + + NSString *testID = dictionary[@"testID"]; + if (testID) + { + barButtonItem.accessibilityIdentifier = testID; + } + + return barButtonItem; } - (UIColor *)color:(UIColor *)color defaultColor:(UIColor *)defaultColor { - if (color) { - return color; - } else if (defaultColor) { - return defaultColor; - } - - return nil; + if (color) { + return color; + } else if (defaultColor) { + return defaultColor; + } + + return nil; } - (id)getValue:(id)value withDefault:(id)defaultValue { - return value ? value : defaultValue; + return value ? value : defaultValue; } - (UIEdgeInsets)leftButtonInsets:(RNNInsetsOptions *)defaultInsets { - return UIEdgeInsetsMake([defaultInsets.top getWithDefaultValue:0], - [defaultInsets.left getWithDefaultValue:0], - [defaultInsets.bottom getWithDefaultValue:0], - [defaultInsets.right getWithDefaultValue:15]); + return UIEdgeInsetsMake([defaultInsets.top getWithDefaultValue:0], + [defaultInsets.left getWithDefaultValue:0], + [defaultInsets.bottom getWithDefaultValue:0], + [defaultInsets.right getWithDefaultValue:15]); } - (UIEdgeInsets)rightButtonInsets:(RNNInsetsOptions *)defaultInsets { - return UIEdgeInsetsMake([defaultInsets.top getWithDefaultValue:0], - [defaultInsets.left getWithDefaultValue:15], - [defaultInsets.bottom getWithDefaultValue:0], - [defaultInsets.right getWithDefaultValue:0]); + return UIEdgeInsetsMake([defaultInsets.top getWithDefaultValue:0], + [defaultInsets.left getWithDefaultValue:15], + [defaultInsets.bottom getWithDefaultValue:0], + [defaultInsets.right getWithDefaultValue:0]); } @end diff --git a/lib/ios/RNNReactComponentRegistry.m b/lib/ios/RNNReactComponentRegistry.m index bdaa582ad2b..1ad6f941d5e 100644 --- a/lib/ios/RNNReactComponentRegistry.m +++ b/lib/ios/RNNReactComponentRegistry.m @@ -17,12 +17,12 @@ - (instancetype)initWithCreator:(id)creator { } - (RNNReactView *)createComponentIfNotExists:(RNNComponentOptions *)component parentComponentId:(NSString *)parentComponentId reactViewReadyBlock:(RNNReactViewReadyCompletionBlock)reactViewReadyBlock { - NSMutableDictionary* parentComponentDict = [self componentsForParentId:parentComponentId]; + NSMapTable* parentComponentDict = [self componentsForParentId:parentComponentId]; - RNNReactView* reactView = parentComponentDict[component.componentId.get]; + RNNReactView* reactView = [parentComponentDict objectForKey:component.componentId.get]; if (!reactView) { reactView = (RNNReactView *)[_creator createRootViewFromComponentOptions:component reactViewReadyBlock:reactViewReadyBlock]; - parentComponentDict[component.componentId.get] = reactView; + [parentComponentDict setObject:reactView forKey:component.componentId.get]; } else if (reactViewReadyBlock) { reactViewReadyBlock(); } @@ -30,9 +30,9 @@ - (RNNReactView *)createComponentIfNotExists:(RNNComponentOptions *)component pa return reactView; } -- (NSMutableDictionary *)componentsForParentId:(NSString *)parentComponentId { +- (NSMapTable *)componentsForParentId:(NSString *)parentComponentId { if (![_componentStore objectForKey:parentComponentId]) { - [_componentStore setObject:[NSMutableDictionary new] forKey:parentComponentId];; + [_componentStore setObject:[NSMapTable weakToStrongObjectsMapTable] forKey:parentComponentId];; } return [_componentStore objectForKey:parentComponentId];; @@ -49,10 +49,10 @@ - (void)removeComponent:(NSString *)componentId { } - (void)removeChildComponent:(NSString *)childId { - NSMutableDictionary* parent; + NSMapTable* parent; NSEnumerator *enumerator = _componentStore.objectEnumerator; while ((parent = enumerator.nextObject)) { - if (parent[childId]) { + if ([parent objectForKey:childId]) { [parent removeObjectForKey:childId]; return; } diff --git a/lib/ios/RNNUIBarButtonItem.h b/lib/ios/RNNUIBarButtonItem.h index 9a4db8d7adf..29c074cd8ee 100644 --- a/lib/ios/RNNUIBarButtonItem.h +++ b/lib/ios/RNNUIBarButtonItem.h @@ -9,7 +9,7 @@ -(instancetype)init:(NSString*)buttonId withIcon:(UIImage*)iconImage; -(instancetype)init:(NSString*)buttonId withTitle:(NSString*)title; --(instancetype)init:(NSString*)buttonId withCustomView:(RCTRootView *)reactView componentRegistry:(RNNReactComponentRegistry *)componentRegistry; +-(instancetype)init:(NSString*)buttonId withCustomView:(RCTRootView *)reactView; -(instancetype)init:(NSString*)buttonId withSystemItem:(NSString*)systemItemName; @end diff --git a/lib/ios/RNNUIBarButtonItem.m b/lib/ios/RNNUIBarButtonItem.m index 32b78108923..a3adf33e5a6 100644 --- a/lib/ios/RNNUIBarButtonItem.m +++ b/lib/ios/RNNUIBarButtonItem.m @@ -7,7 +7,6 @@ @interface RNNUIBarButtonItem () @property (nonatomic, strong) NSLayoutConstraint *widthConstraint; @property (nonatomic, strong) NSLayoutConstraint *heightConstraint; -@property (nonatomic, weak) RNNReactComponentRegistry *componentRegistry; @end @@ -29,29 +28,28 @@ -(instancetype)init:(NSString*)buttonId withTitle:(NSString*)title { return self; } --(instancetype)init:(NSString*)buttonId withCustomView:(RCTRootView *)reactView componentRegistry:(RNNReactComponentRegistry *)componentRegistry { +-(instancetype)init:(NSString*)buttonId withCustomView:(RCTRootView *)reactView { self = [super initWithCustomView:reactView]; - self.componentRegistry = componentRegistry; reactView.sizeFlexibility = RCTRootViewSizeFlexibilityWidthAndHeight; reactView.delegate = self; reactView.backgroundColor = [UIColor clearColor]; - reactView.hidden = YES; - + + [NSLayoutConstraint deactivateConstraints:reactView.constraints]; self.widthConstraint = [NSLayoutConstraint constraintWithItem:reactView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 - constant:1.0]; + constant:reactView.intrinsicContentSize.width]; self.heightConstraint = [NSLayoutConstraint constraintWithItem:reactView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 - constant:1.0]; + constant:reactView.intrinsicContentSize.height]; [NSLayoutConstraint activateConstraints:@[self.widthConstraint, self.heightConstraint]]; self.buttonId = buttonId; return self; @@ -65,7 +63,6 @@ - (instancetype)init:(NSString*)buttonId withSystemItem:(NSString *)systemItemNa } - (void)rootViewDidChangeIntrinsicSize:(RCTRootView *)rootView { - rootView.hidden = NO; self.widthConstraint.constant = rootView.intrinsicContentSize.width; self.heightConstraint.constant = rootView.intrinsicContentSize.height; [rootView setNeedsUpdateConstraints]; @@ -78,11 +75,4 @@ - (void)onButtonPressed { afterDelay:0]; } -- (void)dealloc { - if ([self.customView isKindOfClass:[RNNReactView class]]) { - RNNReactView* customView = self.customView; - [self.componentRegistry removeChildComponent:customView.componentId]; - } -} - @end diff --git a/lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj b/lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj index e2426b886ca..e996dcaac36 100644 --- a/lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj +++ b/lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj @@ -224,6 +224,8 @@ 50CE8503217C6C9B00084EBF /* RNNSideMenuPresenterTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 50CE8502217C6C9B00084EBF /* RNNSideMenuPresenterTest.m */; }; 50D031342005149000386B3D /* RNNOverlayManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 50D031322005149000386B3D /* RNNOverlayManager.h */; }; 50D031352005149000386B3D /* RNNOverlayManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 50D031332005149000386B3D /* RNNOverlayManager.m */; }; + 50DE2E45238EA14E005CD5F4 /* NSArray+utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 50DE2E43238EA14E005CD5F4 /* NSArray+utils.h */; }; + 50DE2E46238EA14E005CD5F4 /* NSArray+utils.m in Sources */ = {isa = PBXBuildFile; fileRef = 50DE2E44238EA14E005CD5F4 /* NSArray+utils.m */; }; 50E02BD821A6EE0F00A43942 /* SideMenuOpenMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 50E02BD621A6EE0F00A43942 /* SideMenuOpenMode.h */; }; 50E02BD921A6EE0F00A43942 /* SideMenuOpenMode.m in Sources */ = {isa = PBXBuildFile; fileRef = 50E02BD721A6EE0F00A43942 /* SideMenuOpenMode.m */; }; 50E02BDC21A6EE7900A43942 /* SideMenuOpenGestureModeParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 50E02BDA21A6EE7900A43942 /* SideMenuOpenGestureModeParser.m */; }; @@ -575,6 +577,8 @@ 50D031322005149000386B3D /* RNNOverlayManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNOverlayManager.h; sourceTree = ""; }; 50D031332005149000386B3D /* RNNOverlayManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNOverlayManager.m; sourceTree = ""; }; 50DA74CF232F80FE004A00C1 /* RCTConvert+UIFontWeight.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RCTConvert+UIFontWeight.h"; sourceTree = ""; }; + 50DE2E43238EA14E005CD5F4 /* NSArray+utils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSArray+utils.h"; sourceTree = ""; }; + 50DE2E44238EA14E005CD5F4 /* NSArray+utils.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSArray+utils.m"; sourceTree = ""; }; 50E02BD521A6E54B00A43942 /* RCTConvert+SideMenuOpenGestureMode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RCTConvert+SideMenuOpenGestureMode.h"; sourceTree = ""; }; 50E02BD621A6EE0F00A43942 /* SideMenuOpenMode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SideMenuOpenMode.h; sourceTree = ""; }; 50E02BD721A6EE0F00A43942 /* SideMenuOpenMode.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SideMenuOpenMode.m; sourceTree = ""; }; @@ -1179,6 +1183,8 @@ E5F6C39E22DB4D0E0093C2CE /* UIViewController+Utils.m */, 50A409C8238D444900D5FF7D /* UINavigationBar+utils.h */, 50A409C9238D444900D5FF7D /* UINavigationBar+utils.m */, + 50DE2E43238EA14E005CD5F4 /* NSArray+utils.h */, + 50DE2E44238EA14E005CD5F4 /* NSArray+utils.m */, ); name = Utils; sourceTree = ""; @@ -1307,6 +1313,7 @@ 50644A2020E11A720026709C /* Constants.h in Headers */, E5F6C3AF22DB4D0F0093C2CE /* UIView+Utils.h in Headers */, 5012241E217366D4000F5F98 /* ColorParser.h in Headers */, + 50DE2E45238EA14E005CD5F4 /* NSArray+utils.h in Headers */, E8367B801F7A8A4700675C05 /* VICMAImageView.h in Headers */, 263905E61E4CAC950023D7D3 /* RNNSideMenuChildVC.h in Headers */, 50F5DFC51F407AA0001A00BC /* RNNStackController.h in Headers */, @@ -1527,6 +1534,7 @@ 50E5F78E223F9FAF002AFEAD /* RNNElementTransitionOptions.m in Sources */, 7365071221E4B16F004E020F /* RCTConvert+UIBarButtonSystemItem.m in Sources */, 5012241B21736678000F5F98 /* Image.m in Sources */, + 50DE2E46238EA14E005CD5F4 /* NSArray+utils.m in Sources */, 50495943216F5E5D006D2B81 /* NullBool.m in Sources */, 5038A3C7216E2D93009280BC /* Number.m in Sources */, E5F6C3A622DB4D0F0093C2CE /* UIViewController+Utils.m in Sources */,