Просмотр исходного кода

Create new UITabBarItem instance on each bottomTab update (#6018)

Fix an issue where bottomTab.testID doesn't get updated on mergeOptions unless a new UITabBarItem is created. Look like an issue in iOS where tabBarItem.accessibilityIdentifier doesn't get updated unless a new tabBarItem is created.
Yogev Ben David 4 лет назад
Родитель
Сommit
3757ff7aa6
No account linked to committer's email address

+ 0
- 2
lib/ios/BottomTabAppearancePresenter.h Просмотреть файл

@@ -3,6 +3,4 @@
3 3
 API_AVAILABLE(ios(13.0))
4 4
 @interface BottomTabAppearancePresenter : BottomTabPresenter
5 5
 
6
-- (instancetype)initWithDefaultOptions:(RNNNavigationOptions *)defaultOptions children:(NSArray<UIViewController *> *)children;
7
-
8 6
 @end

+ 1
- 9
lib/ios/BottomTabAppearancePresenter.m Просмотреть файл

@@ -3,16 +3,8 @@
3 3
 
4 4
 @implementation BottomTabAppearancePresenter
5 5
 
6
-- (instancetype)initWithDefaultOptions:(RNNNavigationOptions *)defaultOptions children:(NSArray<UIViewController *> *)children {
7
-    self = [super initWithDefaultOptions:defaultOptions];
8
-    for (UIViewController* child in children) {
9
-        child.tabBarItem.standardAppearance = [[UITabBarAppearance alloc] init];
10
-    }
11
-    return self;
12
-}
13
-
14 6
 - (void)createTabBarItem:(UIViewController *)child bottomTabOptions:(RNNBottomTabOptions *)bottomTabOptions {
15
-    child.tabBarItem = [TabBarItemAppearanceCreator updateTabBarItem:child.tabBarItem bottomTabOptions:bottomTabOptions];
7
+    child.tabBarItem = [TabBarItemAppearanceCreator createTabBarItem:bottomTabOptions mergeItem:child.tabBarItem];
16 8
 }
17 9
 
18 10
 @end

+ 3
- 3
lib/ios/BottomTabPresenter.m Просмотреть файл

@@ -15,21 +15,21 @@
15 15
 - (void)applyOptionsOnWillMoveToParentViewController:(RNNNavigationOptions *)options  child:(UIViewController *)child {
16 16
     RNNNavigationOptions * withDefault = [options withDefault:self.defaultOptions];
17 17
     
18
+    [self createTabBarItem:child bottomTabOptions:withDefault.bottomTab];
18 19
     [child setTabBarItemBadge:[withDefault.bottomTab.badge getWithDefaultValue:[NSNull null]]];
19 20
     [child setTabBarItemBadgeColor:[withDefault.bottomTab.badgeColor getWithDefaultValue:nil]];
20
-    [self createTabBarItem:child bottomTabOptions:withDefault.bottomTab];
21 21
 }
22 22
 
23 23
 - (void)mergeOptions:(RNNNavigationOptions *)options resolvedOptions:(RNNNavigationOptions *)resolvedOptions child:(UIViewController *)child {
24 24
     RNNNavigationOptions* withDefault = (RNNNavigationOptions *) [[resolvedOptions withDefault:self.defaultOptions] overrideOptions:options];
25 25
     
26
+    if (options.bottomTab.hasValue) [self createTabBarItem:child bottomTabOptions:withDefault.bottomTab];
26 27
     if (options.bottomTab.badge.hasValue) [child setTabBarItemBadge:options.bottomTab.badge.get];
27 28
     if (options.bottomTab.badgeColor.hasValue) [child setTabBarItemBadgeColor:options.bottomTab.badgeColor.get];
28
-    if (options.bottomTab.hasValue) [self createTabBarItem:child bottomTabOptions:withDefault.bottomTab];
29 29
 }
30 30
 
31 31
 - (void)createTabBarItem:(UIViewController *)child bottomTabOptions:(RNNBottomTabOptions *)bottomTabOptions {
32
-    child.tabBarItem = [RNNTabBarItemCreator updateTabBarItem:child.tabBarItem bottomTabOptions:bottomTabOptions];
32
+    child.tabBarItem = [RNNTabBarItemCreator createTabBarItem:bottomTabOptions mergeItem:child.tabBarItem];
33 33
 }
34 34
 
35 35
 @end

+ 1
- 1
lib/ios/BottomTabPresenterCreator.h Просмотреть файл

@@ -3,6 +3,6 @@
3 3
 
4 4
 @interface BottomTabPresenterCreator : NSObject
5 5
 
6
-+ (BottomTabPresenter *)createWithDefaultOptions:(RNNNavigationOptions *)defaultOptions children:(NSArray<UIViewController *> *)children;
6
++ (BottomTabPresenter *)createWithDefaultOptions:(RNNNavigationOptions *)defaultOptions;
7 7
 
8 8
 @end

+ 2
- 2
lib/ios/BottomTabPresenterCreator.m Просмотреть файл

@@ -3,9 +3,9 @@
3 3
 
4 4
 @implementation BottomTabPresenterCreator
5 5
 
6
-+ (BottomTabPresenter *)createWithDefaultOptions:(RNNNavigationOptions *)defaultOptions children:(NSArray<UIViewController *> *)children {
6
++ (BottomTabPresenter *)createWithDefaultOptions:(RNNNavigationOptions *)defaultOptions {
7 7
 	if (@available(iOS 13.0, *)) {
8
-		return [[BottomTabAppearancePresenter alloc] initWithDefaultOptions:defaultOptions children:children];
8
+		return [[BottomTabAppearancePresenter alloc] initWithDefaultOptions:defaultOptions];
9 9
 	} else {
10 10
 		return [[BottomTabPresenter alloc] initWithDefaultOptions:defaultOptions];
11 11
 	}

+ 1
- 1
lib/ios/RNNControllerFactory.m Просмотреть файл

@@ -152,7 +152,7 @@
152 152
     RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:node.data[@"options"]];
153 153
     RNNBottomTabsPresenter* presenter = [BottomTabsPresenterCreator createWithDefaultOptions:_defaultOptions];
154 154
     NSArray *childViewControllers = [self extractChildrenViewControllersFromNode:node];
155
-    BottomTabPresenter* bottomTabPresenter = [BottomTabPresenterCreator createWithDefaultOptions:_defaultOptions children:childViewControllers];;
155
+    BottomTabPresenter* bottomTabPresenter = [BottomTabPresenterCreator createWithDefaultOptions:_defaultOptions];
156 156
     RNNDotIndicatorPresenter* dotIndicatorPresenter = [[RNNDotIndicatorPresenter alloc] initWithDefaultOptions:_defaultOptions];
157 157
 	BottomTabsBaseAttacher* bottomTabsAttacher = [_bottomTabsAttachModeFactory fromOptions:options];
158 158
     

+ 3
- 1
lib/ios/RNNTabBarItemCreator.h Просмотреть файл

@@ -4,7 +4,9 @@
4 4
 
5 5
 @interface RNNTabBarItemCreator : NSObject
6 6
 
7
-+ (UITabBarItem *)updateTabBarItem:(UITabBarItem *)tabItem bottomTabOptions:(RNNBottomTabOptions *)bottomTabOptions;
7
++ (UITabBarItem *)createTabBarItem:(RNNBottomTabOptions *)bottomTabOptions mergeItem:(UITabBarItem *)mergeItem;
8
+
9
++ (UITabBarItem *)createTabBarItem:(UITabBarItem *)mergeItem;
8 10
 
9 11
 + (void)setTitleAttributes:(UITabBarItem *)tabItem titleAttributes:(NSDictionary *)titleAttributes;
10 12
 

+ 6
- 1
lib/ios/RNNTabBarItemCreator.m Просмотреть файл

@@ -4,7 +4,12 @@
4 4
 
5 5
 @implementation RNNTabBarItemCreator
6 6
 
7
-+ (UITabBarItem *)updateTabBarItem:(UITabBarItem *)tabItem bottomTabOptions:(RNNBottomTabOptions *)bottomTabOptions {
7
++ (UITabBarItem *)createTabBarItem:(UITabBarItem *)mergeItem {
8
+    return [UITabBarItem new];
9
+}
10
+
11
++ (UITabBarItem *)createTabBarItem:(RNNBottomTabOptions *)bottomTabOptions mergeItem:(UITabBarItem *)mergeItem {
12
+    UITabBarItem* tabItem = [self createTabBarItem:mergeItem];
8 13
 	UIImage* icon = [bottomTabOptions.icon getWithDefaultValue:nil];
9 14
 	UIImage* selectedIcon = [bottomTabOptions.selectedIcon getWithDefaultValue:icon];
10 15
 	UIColor* iconColor = [bottomTabOptions.iconColor getWithDefaultValue:nil];

+ 1
- 0
lib/ios/TabBarItemAppearanceCreator.h Просмотреть файл

@@ -1,5 +1,6 @@
1 1
 #import "RNNTabBarItemCreator.h"
2 2
 
3
+API_AVAILABLE(ios(13.0))
3 4
 @interface TabBarItemAppearanceCreator : RNNTabBarItemCreator
4 5
 
5 6
 @end

+ 6
- 0
lib/ios/TabBarItemAppearanceCreator.m Просмотреть файл

@@ -2,6 +2,12 @@
2 2
 
3 3
 @implementation TabBarItemAppearanceCreator
4 4
 
5
++ (UITabBarItem *)createTabBarItem:(UITabBarItem *)mergeItem {
6
+    UITabBarItem* tabBarItem = [super createTabBarItem:mergeItem];
7
+    tabBarItem.standardAppearance = mergeItem.standardAppearance ?: [[UITabBarAppearance alloc] init];
8
+    return tabBarItem;
9
+}
10
+
5 11
 + (void)setTitleAttributes:(UITabBarItem *)tabItem titleAttributes:(NSDictionary *)titleAttributes {
6 12
     tabItem.standardAppearance.stackedLayoutAppearance.normal.titleTextAttributes = titleAttributes;
7 13
 }

+ 14
- 0
playground/ios/NavigationTests/BottomTabPresenterTest.m Просмотреть файл

@@ -52,4 +52,18 @@
52 52
 	XCTAssertEqual(self.componentViewController.tabBarItem.title, @"title");
53 53
 }
54 54
 
55
+- (void)testMergeOptions_shouldCreateNewTabBarItemInstance {
56
+	RNNNavigationOptions* defaultOptions = [[RNNNavigationOptions alloc] initEmptyOptions];
57
+	defaultOptions.bottomTab.selectedIconColor = [Color withColor:UIColor.greenColor];
58
+	self.uut.defaultOptions = defaultOptions;
59
+	
60
+	RNNNavigationOptions* mergeOptions = [[RNNNavigationOptions alloc] initEmptyOptions];
61
+	mergeOptions.bottomTab.text = [[Text alloc] initWithValue:@"title"];
62
+	
63
+	UITabBarItem* currentTabBarItem = self.componentViewController.tabBarItem;
64
+	[self.uut mergeOptions:mergeOptions resolvedOptions:self.options child:self.componentViewController];
65
+	UITabBarItem* newTabBarItem = self.componentViewController.tabBarItem;
66
+	XCTAssertNotEqual(currentTabBarItem, newTabBarItem);
67
+}
68
+
55 69
 @end

+ 1
- 1
playground/ios/NavigationTests/RNNBottomTabsAppearancePresenterTest.m Просмотреть файл

@@ -25,7 +25,7 @@
25 25
 	self.children = @[[[RNNComponentViewController alloc] initWithLayoutInfo:nil rootViewCreator:nil eventEmitter:nil presenter:[[RNNComponentPresenter alloc] initWithDefaultOptions:nil] options:nil defaultOptions:nil]];
26 26
 	self.dotIndicatorPresenter = [OCMockObject partialMockForObject:[[RNNDotIndicatorPresenter alloc] initWithDefaultOptions:nil]];
27 27
     self.uut = [OCMockObject partialMockForObject:[BottomTabsPresenterCreator createWithDefaultOptions:nil]];
28
-	self.boundViewController = [OCMockObject partialMockForObject:[[RNNBottomTabsController alloc] initWithLayoutInfo:nil creator:nil options:nil defaultOptions:nil presenter:self.uut bottomTabPresenter:[BottomTabPresenterCreator createWithDefaultOptions:nil children:self.children] dotIndicatorPresenter:self.dotIndicatorPresenter eventEmitter:nil childViewControllers:self.children bottomTabsAttacher:nil]];
28
+	self.boundViewController = [OCMockObject partialMockForObject:[[RNNBottomTabsController alloc] initWithLayoutInfo:nil creator:nil options:nil defaultOptions:nil presenter:self.uut bottomTabPresenter:[BottomTabPresenterCreator createWithDefaultOptions:nil] dotIndicatorPresenter:self.dotIndicatorPresenter eventEmitter:nil childViewControllers:self.children bottomTabsAttacher:nil]];
29 29
     [self.uut bindViewController:self.boundViewController];
30 30
     self.options = [[RNNNavigationOptions alloc] initEmptyOptions];
31 31
 }

+ 1
- 1
playground/ios/NavigationTests/RNNBottomTabsController+Helpers.m Просмотреть файл

@@ -11,7 +11,7 @@
11 11
 
12 12
 + (RNNBottomTabsController *)createWithChildren:(NSArray *)children {
13 13
 	RNNNavigationOptions* defaultOptions = [[RNNNavigationOptions alloc] initEmptyOptions];
14
-	return [[RNNBottomTabsController alloc] initWithLayoutInfo:nil creator:nil options:[[RNNNavigationOptions alloc] initEmptyOptions] defaultOptions:defaultOptions presenter:[BottomTabsPresenterCreator createWithDefaultOptions:defaultOptions] bottomTabPresenter:[BottomTabPresenterCreator createWithDefaultOptions:defaultOptions children:children] dotIndicatorPresenter:[[RNNDotIndicatorPresenter alloc] initWithDefaultOptions:defaultOptions] eventEmitter:nil childViewControllers:children bottomTabsAttacher:nil];
14
+	return [[RNNBottomTabsController alloc] initWithLayoutInfo:nil creator:nil options:[[RNNNavigationOptions alloc] initEmptyOptions] defaultOptions:defaultOptions presenter:[BottomTabsPresenterCreator createWithDefaultOptions:defaultOptions] bottomTabPresenter:[BottomTabPresenterCreator createWithDefaultOptions:defaultOptions] dotIndicatorPresenter:[[RNNDotIndicatorPresenter alloc] initWithDefaultOptions:defaultOptions] eventEmitter:nil childViewControllers:children bottomTabsAttacher:nil];
15 15
 }
16 16
 
17 17
 @end

+ 1
- 1
playground/ios/NavigationTests/RNNDotIndicatorPresenterTest.m Просмотреть файл

@@ -20,7 +20,7 @@
20 20
 - (void)setUp {
21 21
     [super setUp];
22 22
 	self.child = [self createChild];
23
-	self.bottomTabPresenter = [BottomTabPresenterCreator createWithDefaultOptions:nil children:@[self.child]];
23
+	self.bottomTabPresenter = [BottomTabPresenterCreator createWithDefaultOptions:nil];
24 24
     self.uut = [OCMockObject partialMockForObject:[RNNDotIndicatorPresenter new]];
25 25
     self.bottomTabs = [OCMockObject partialMockForObject:[RNNBottomTabsController createWithChildren:@[self.child]]];
26 26
 

+ 0
- 2
playground/ios/NavigationTests/RNNRootViewControllerTest.m Просмотреть файл

@@ -180,8 +180,6 @@
180 180
 	NSString* tabBadgeInput = @"5";
181 181
 	self.options.bottomTab.badge = [[Text alloc] initWithValue:tabBadgeInput];
182 182
 	NSMutableArray* controllers = [NSMutableArray new];
183
-	UITabBarItem* item = [[UITabBarItem alloc] initWithTitle:@"A Tab" image:nil tag:1];
184
-	[self.uut setTabBarItem:item];
185 183
 	[controllers addObject:self.uut];
186 184
 	__unused RNNBottomTabsController* vc = [RNNBottomTabsController createWithChildren:controllers];
187 185
 	[self.uut willMoveToParentViewController:vc];

+ 1
- 1
playground/ios/NavigationTests/RNNTabBarControllerTest.m Просмотреть файл

@@ -28,7 +28,7 @@
28 28
     self.mockTabBarPresenter = [OCMockObject partialMockForObject:[[RNNBottomTabsPresenter alloc] init]];
29 29
     self.mockChildViewController = [OCMockObject partialMockForObject:[RNNComponentViewController new]];
30 30
     self.mockEventEmitter = [OCMockObject partialMockForObject:[RNNEventEmitter new]];
31
-	self.originalUut = [[RNNBottomTabsController alloc] initWithLayoutInfo:nil creator:nil options:[[RNNNavigationOptions alloc] initWithDict:@{}] defaultOptions:nil presenter:self.mockTabBarPresenter bottomTabPresenter:[BottomTabPresenterCreator createWithDefaultOptions:nil children:children] dotIndicatorPresenter:[[RNNDotIndicatorPresenter alloc] initWithDefaultOptions:nil] eventEmitter:self.mockEventEmitter childViewControllers:children bottomTabsAttacher:nil];
31
+	self.originalUut = [[RNNBottomTabsController alloc] initWithLayoutInfo:nil creator:nil options:[[RNNNavigationOptions alloc] initWithDict:@{}] defaultOptions:nil presenter:self.mockTabBarPresenter bottomTabPresenter:[BottomTabPresenterCreator createWithDefaultOptions:nil] dotIndicatorPresenter:[[RNNDotIndicatorPresenter alloc] initWithDefaultOptions:nil] eventEmitter:self.mockEventEmitter childViewControllers:children bottomTabsAttacher:nil];
32 32
     self.uut = [OCMockObject partialMockForObject:self.originalUut];
33 33
     OCMStub([self.uut selectedViewController]).andReturn(self.mockChildViewController);
34 34
 }