Parcourir la source

Fix options resolving issues (#5450)

* Enabled option was wrongly consumed after it was merged. That meant that the next time SideMenu options were applied, the wrong enabled value was applied
* supportedInterfaceOrientations didn't take default orientation value into account
* mergeOptions didn't save the new options in the ViewControllers current options
* SideMenu always returned the centre ViewController as the current child and didn't take open SideMenu into account

Fixes #5444
Guy Carmeli il y a 5 ans
Parent
révision
5816fb8a78
No account linked to committer's email address

+ 2
- 0
lib/ios/RNNBasePresenter.h Voir le fichier

@@ -34,5 +34,7 @@ typedef void (^RNNReactViewReadyCompletionBlock)(void);
34 34
 
35 35
 - (UIStatusBarStyle)getStatusBarStyle:(RNNNavigationOptions *)resolvedOptions;
36 36
 
37
+- (UIInterfaceOrientationMask)getOrientation:(RNNNavigationOptions *)options;
38
+
37 39
 - (BOOL)isStatusBarVisibility:(UINavigationController *)stack resolvedOptions:(RNNNavigationOptions *)resolvedOptions;
38 40
 @end

+ 4
- 0
lib/ios/RNNBasePresenter.m Voir le fichier

@@ -174,6 +174,10 @@
174 174
     }
175 175
 }
176 176
 
177
+- (UIInterfaceOrientationMask)getOrientation:(RNNNavigationOptions *)options {
178
+    return [options withDefault:[self defaultOptions]].layout.supportedOrientations;
179
+}
180
+
177 181
 - (BOOL)isStatusBarVisibility:(UINavigationController *)stack resolvedOptions:(RNNNavigationOptions *)resolvedOptions {
178 182
     RNNNavigationOptions *withDefault = [resolvedOptions withDefault:[self defaultOptions]];
179 183
     if (withDefault.statusBar.visible.hasValue) {

+ 0
- 4
lib/ios/RNNNavigationController.m Voir le fichier

@@ -23,10 +23,6 @@ const NSInteger TOP_BAR_TRANSPARENT_TAG = 78264803;
23 23
 	return self.navigationBar.frame.size.height;
24 24
 }
25 25
 
26
-- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
27
-	return self.getCurrentChild.supportedInterfaceOrientations;
28
-}
29
-
30 26
 - (UINavigationController *)navigationController {
31 27
 	return self;
32 28
 }

+ 1
- 5
lib/ios/RNNRootViewController.m Voir le fichier

@@ -33,7 +33,7 @@
33 33
 
34 34
 - (void)mergeOptions:(RNNNavigationOptions *)options {
35 35
 	[_presenter mergeOptions:options currentOptions:self.options];
36
-	[self.parentViewController mergeOptions:options];
36
+	[self.parentViewController mergeChildOptions:options];
37 37
 }
38 38
 
39 39
 - (void)overrideOptions:(RNNNavigationOptions *)options {
@@ -123,10 +123,6 @@
123 123
 	return [_presenter getStatusBarStyle:[self resolveOptions]];
124 124
 }
125 125
 
126
-- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
127
-	return self.resolveOptions.layout.supportedOrientations;
128
-}
129
-
130 126
 - (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
131 127
 	RNNRootViewController* vc =  (RNNRootViewController*)viewController;
132 128
 	if (![[vc.self.resolveOptions.topBar.backButton.transition getWithDefaultValue:@""] isEqualToString:@"custom"]){

+ 0
- 4
lib/ios/RNNSideMenuChildVC.m Voir le fichier

@@ -43,8 +43,4 @@
43 43
 	return [[self presenter] getStatusBarStyle:[self resolveOptions]];
44 44
 }
45 45
 
46
-- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
47
-	return self.child.supportedInterfaceOrientations;
48
-}
49
-
50 46
 @end

+ 11
- 7
lib/ios/RNNSideMenuController.m Voir le fichier

@@ -96,7 +96,7 @@
96 96
 	for (id controller in controllers) {
97 97
 		if ([controller isKindOfClass:[RNNSideMenuChildVC class]]) {
98 98
 			RNNSideMenuChildVC *child = (RNNSideMenuChildVC*)controller;
99
-			
99
+
100 100
 			if (child.type == RNNSideMenuChildTypeCenter) {
101 101
 				self.center = child;
102 102
 			}
@@ -106,10 +106,10 @@
106 106
 			else if(child.type == RNNSideMenuChildTypeRight) {
107 107
 				self.right = child;
108 108
 			}
109
-			
109
+
110 110
 			[self addChildViewController:child];
111 111
 		}
112
-		
112
+
113 113
 		else {
114 114
 			@throw [NSException exceptionWithName:@"UnknownSideMenuControllerType" reason:[@"Unknown side menu type " stringByAppendingString:[controller description]] userInfo:nil];
115 115
 		}
@@ -120,8 +120,8 @@
120 120
 	return self.openedViewController.preferredStatusBarStyle;
121 121
 }
122 122
 
123
-- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
124
-	return self.openedViewController.supportedInterfaceOrientations;
123
+- (UIViewController<RNNLayoutProtocol> *)getCurrentChild {
124
+	return self.openedViewController;
125 125
 }
126 126
 
127 127
 - (UIViewController *)openedViewController {
@@ -137,8 +137,12 @@
137 137
 	}
138 138
 }
139 139
 
140
-- (UIViewController<RNNLayoutProtocol> *)getCurrentChild {
141
-	return self.center;
140
+- (RNNNavigationOptions *)resolveOptions {
141
+    RNNNavigationOptions * options = super.resolveOptions;
142
+    if (self.openedViewController != self.center) {
143
+        [options.sideMenu mergeOptions:self.center.resolveOptions.sideMenu];
144
+    }
145
+    return options;
142 146
 }
143 147
 
144 148
 - (CGFloat)getTopBarHeight {

+ 0
- 1
lib/ios/RNNSideMenuOptions.m Voir le fichier

@@ -1,5 +1,4 @@
1 1
 #import "RNNSideMenuOptions.h"
2
-#import "RNNSideMenuController.h"
3 2
 #import "SideMenuOpenGestureModeParser.h"
4 3
 
5 4
 @implementation RNNSideMenuOptions

+ 0
- 2
lib/ios/RNNSideMenuPresenter.m Voir le fichier

@@ -66,12 +66,10 @@
66 66
 	
67 67
 	if (newOptions.sideMenu.left.enabled.hasValue) {
68 68
 		[sideMenuController side:MMDrawerSideLeft enabled:newOptions.sideMenu.left.enabled.get];
69
-		[newOptions.sideMenu.left.enabled consume];
70 69
 	}
71 70
 	
72 71
 	if (newOptions.sideMenu.right.enabled.hasValue) {
73 72
 		[sideMenuController side:MMDrawerSideRight enabled:newOptions.sideMenu.right.enabled.get];
74
-		[newOptions.sideMenu.right.enabled consume];
75 73
 	}
76 74
 	
77 75
 	if (newOptions.sideMenu.left.visible.hasValue) {

+ 0
- 4
lib/ios/RNNTabBarController.m Voir le fichier

@@ -24,10 +24,6 @@
24 24
     return [super getTopBarHeight];
25 25
 }
26 26
 
27
-- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
28
-	return self.selectedViewController.supportedInterfaceOrientations;
29
-}
30
-
31 27
 - (void)setSelectedIndexByComponentID:(NSString *)componentID {
32 28
 	for (id child in self.childViewControllers) {
33 29
 		UIViewController<RNNLayoutProtocol>* vc = child;

+ 0
- 2
lib/ios/RNNViewControllerPresenter.m Voir le fichier

@@ -225,6 +225,4 @@
225 225
 - (void)dealloc {
226 226
 	[_componentRegistry clearComponentsForParentId:self.boundComponentId];
227 227
 }
228
-
229
-
230 228
 @end

+ 7
- 14
lib/ios/ReactNativeNavigationTests/RNNRootViewControllerTest.m Voir le fichier

@@ -373,11 +373,9 @@
373 373
 -(void)testOrientationTabsController_portrait {
374 374
 	NSArray* supportedOrientations = @[@"portrait"];
375 375
 	self.options.layout.orientation = supportedOrientations;
376
-	__unused RNNTabBarController* vc = [[RNNTabBarController alloc] init];
377
-	NSMutableArray* controllers = [NSMutableArray new];
376
+	NSMutableArray* controllers = [[NSMutableArray alloc] initWithArray:@[self.uut]];
377
+    __unused RNNTabBarController* vc = [[RNNTabBarController alloc] initWithLayoutInfo:nil creator:nil options:[[RNNNavigationOptions alloc] initEmptyOptions] defaultOptions:nil presenter:[RNNViewControllerPresenter new] eventEmitter:nil childViewControllers:controllers];
378 378
 
379
-	[controllers addObject:self.uut];
380
-	[vc setViewControllers:controllers];
381 379
 	[self.uut viewWillAppear:false];
382 380
 
383 381
 	UIInterfaceOrientationMask expectedOrientation = UIInterfaceOrientationMaskPortrait;
@@ -387,11 +385,9 @@
387 385
 -(void)testOrientationTabsController_portraitAndLandscape {
388 386
 	NSArray* supportedOrientations = @[@"portrait", @"landscape"];
389 387
 	self.options.layout.orientation = supportedOrientations;
390
-	__unused RNNTabBarController* vc = [[RNNTabBarController alloc] init];
391
-	NSMutableArray* controllers = [NSMutableArray new];
388
+    NSMutableArray* controllers = [[NSMutableArray alloc] initWithArray:@[self.uut]];
389
+    __unused RNNTabBarController* vc = [[RNNTabBarController alloc] initWithLayoutInfo:nil creator:nil options:[[RNNNavigationOptions alloc] initEmptyOptions] defaultOptions:nil presenter:[RNNViewControllerPresenter new] eventEmitter:nil childViewControllers:controllers];
392 390
 
393
-	[controllers addObject:self.uut];
394
-	[vc setViewControllers:controllers];
395 391
 	[self.uut viewWillAppear:false];
396 392
 
397 393
 	UIInterfaceOrientationMask expectedOrientation = (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscape);
@@ -401,11 +397,9 @@
401 397
 -(void)testOrientationTabsController_all {
402 398
 	NSArray* supportedOrientations = @[@"all"];
403 399
 	self.options.layout.orientation = supportedOrientations;
404
-	__unused RNNTabBarController* vc = [[RNNTabBarController alloc] init];
405
-	NSMutableArray* controllers = [NSMutableArray new];
400
+	NSMutableArray* controllers = [[NSMutableArray alloc] initWithArray:@[self.uut]];
401
+	__unused RNNTabBarController* vc = [[RNNTabBarController alloc] initWithLayoutInfo:nil creator:nil options:[[RNNNavigationOptions alloc] initEmptyOptions] defaultOptions:nil presenter:[RNNViewControllerPresenter new] eventEmitter:nil childViewControllers:controllers];
406 402
 
407
-	[controllers addObject:self.uut];
408
-	[vc setViewControllers:controllers];
409 403
 	[self.uut viewWillAppear:false];
410 404
 
411 405
 	UIInterfaceOrientationMask expectedOrientation = UIInterfaceOrientationMaskAll;
@@ -417,7 +411,7 @@
417 411
 	self.uut = [[RNNRootViewController alloc] initWithLayoutInfo:nil rootViewCreator:nil eventEmitter:nil presenter:[RNNViewControllerPresenter new] options:self.options defaultOptions:nil];
418 412
 	RNNNavigationController* nav = [[RNNNavigationController alloc] initWithLayoutInfo:nil creator:_creator options:nil defaultOptions:nil presenter:nil eventEmitter:nil childViewControllers:@[self.uut]];
419 413
 
420
-	RNNUIBarButtonItem* button = (RNNUIBarButtonItem*)[nav.topViewController.navigationItem.rightBarButtonItems objectAtIndex:0];
414
+	RNNUIBarButtonItem* button = (RNNUIBarButtonItem*) nav.topViewController.navigationItem.rightBarButtonItems[0];
421 415
 	NSString* expectedButtonId = @"testId";
422 416
 	NSString* expectedTitle = @"test";
423 417
 	XCTAssertTrue([button.buttonId isEqualToString:expectedButtonId]);
@@ -442,7 +436,6 @@
442 436
 	//TODO: Determine how to tests buttonColor,buttonFontSize and buttonFontWeight?
443 437
 }
444 438
 
445
-
446 439
 -(void)testLeftButtonsWithTitle_withoutStyle {
447 440
 	self.options.topBar.leftButtons = @[@{@"id": @"testId", @"text": @"test"}];
448 441
 	self.uut = [[RNNRootViewController alloc] initWithLayoutInfo:nil rootViewCreator:nil eventEmitter:nil presenter:[RNNViewControllerPresenter new] options:self.options defaultOptions:nil];

+ 34
- 0
lib/ios/ReactNativeNavigationTests/RNNSideMenuControllerTest.m Voir le fichier

@@ -29,4 +29,38 @@
29 29
 	XCTAssertEqual(self.uut.right.child.view.frame.size.width, 150.f);
30 30
 }
31 31
 
32
+- (void)testGetCurrentChild {
33
+    XCTestExpectation *expectation = [self expectationWithDescription:@"Testing Async Method"];
34
+	XCTAssertEqual(_uut.getCurrentChild, _centerVC);
35
+
36
+	[_uut openDrawerSide:MMDrawerSideLeft animated:NO completion:(void (^)(BOOL)) ^{
37
+        XCTAssertEqual(_uut.getCurrentChild, _leftVC);
38
+	}];
39
+
40
+    [_uut closeDrawerAnimated:NO completion:nil];
41
+    [_uut openDrawerSide:MMDrawerSideRight animated:NO completion:(void (^)(BOOL)) ^{
42
+        XCTAssertEqual(_uut.getCurrentChild, _rightVC);
43
+        [expectation fulfill];
44
+    }];
45
+
46
+    [self waitForExpectationsWithTimeout:1 handler:nil];
47
+}
48
+
49
+- (void)testResolveOptions {
50
+    XCTestExpectation *expectation = [self expectationWithDescription:@"Testing Async Method"];
51
+
52
+    RNNNavigationOptions *options = [[RNNNavigationOptions alloc] initEmptyOptions];
53
+    options.sideMenu.left.visible = [[Bool alloc] initWithBOOL:YES];
54
+    [_centerVC overrideOptions:options];
55
+
56
+    XCTAssertTrue(_uut.resolveOptions.sideMenu.left.visible);
57
+
58
+    [_uut openDrawerSide:MMDrawerSideLeft animated:NO completion:^(BOOL finished) {
59
+        XCTAssertTrue(_uut.resolveOptions.sideMenu.left.visible);
60
+        [expectation fulfill];
61
+    }];
62
+
63
+    [self waitForExpectationsWithTimeout:1 handler:nil];
64
+}
65
+
32 66
 @end

+ 1
- 1
lib/ios/ReactNativeNavigationTests/RNNTabBarControllerTest.m Voir le fichier

@@ -100,7 +100,7 @@
100 100
     RNNNavigationOptions *options = [[RNNNavigationOptions alloc] initWithDict:@{}];
101 101
 
102 102
     OCMStub([self.uut parentViewController]).andReturn(parentMock);
103
-    [((RNNRootViewController *) [parentMock expect]) mergeOptions:options];
103
+    [((RNNRootViewController *) [parentMock expect]) mergeChildOptions:options];
104 104
     [self.uut mergeOptions:options];
105 105
     [parentMock verify];
106 106
 }

+ 10
- 1
lib/ios/ReactNativeNavigationTests/UIViewController+LayoutProtocolTest.m Voir le fichier

@@ -102,7 +102,7 @@
102 102
 - (void)testMergeOptions_invokedOnParentViewController {
103 103
     id parent = [OCMockObject partialMockForObject:[RNNNavigationController new]];
104 104
     RNNNavigationOptions * toMerge = [[RNNNavigationOptions alloc] initEmptyOptions];
105
-    [(UIViewController *) [parent expect] mergeOptions:toMerge];
105
+    [(UIViewController *) [parent expect] mergeChildOptions:toMerge];
106 106
 
107 107
     RNNNavigationController* uut = [[RNNNavigationController alloc] initWithLayoutInfo:nil creator:nil options:nil defaultOptions:nil presenter:nil eventEmitter:nil childViewControllers:nil];
108 108
     [parent addChildViewController:uut];
@@ -136,4 +136,13 @@
136 136
     [presenter verify];
137 137
 }
138 138
 
139
+- (void)testMergeOptions_mergedIntoCurrentOptions {
140
+	UIViewController* uut = [[UIViewController alloc] initWithLayoutInfo:nil creator:nil options:[[RNNNavigationOptions alloc] initEmptyOptions] defaultOptions:nil presenter:nil eventEmitter:nil childViewControllers:nil];
141
+	RNNNavigationOptions * toMerge = [[RNNNavigationOptions alloc] initEmptyOptions];
142
+	toMerge.topBar.title.text = [[Text alloc] initWithValue:@"merged"];
143
+
144
+	[uut mergeOptions:toMerge];
145
+	XCTAssertEqual(uut.resolveOptions.topBar.title.text.get, @"merged");
146
+}
147
+
139 148
 @end

+ 2
- 0
lib/ios/UIViewController+LayoutProtocol.h Voir le fichier

@@ -12,6 +12,8 @@ typedef void (^RNNReactViewReadyCompletionBlock)(void);
12 12
 
13 13
 - (void)mergeOptions:(RNNNavigationOptions *)options;
14 14
 
15
+- (void)mergeChildOptions:(RNNNavigationOptions *)options;
16
+
15 17
 - (RNNNavigationOptions *)resolveOptions;
16 18
 
17 19
 - (void)setDefaultOptions:(RNNNavigationOptions *)defaultOptions;

+ 11
- 1
lib/ios/UIViewController+LayoutProtocol.m Voir le fichier

@@ -29,8 +29,14 @@
29 29
 }
30 30
 
31 31
 - (void)mergeOptions:(RNNNavigationOptions *)options {
32
+    [self.options overrideOptions:options];
32 33
 	[self.presenter mergeOptions:options currentOptions:self.resolveOptions];
33
-	[self.parentViewController mergeOptions:options];
34
+    [self.parentViewController mergeChildOptions:options];
35
+}
36
+
37
+- (void)mergeChildOptions:(RNNNavigationOptions *)options {
38
+	[self.presenter mergeOptions:options currentOptions:self.resolveOptions];
39
+	[self.parentViewController mergeChildOptions:options];
34 40
 }
35 41
 
36 42
 - (RNNNavigationOptions *)resolveOptions {
@@ -41,6 +47,10 @@
41 47
 	[self.options overrideOptions:options];
42 48
 }
43 49
 
50
+- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
51
+    return [self.presenter getOrientation:[self resolveOptions]];
52
+}
53
+
44 54
 - (void)renderTreeAndWait:(BOOL)wait perform:(RNNReactViewReadyCompletionBlock)readyBlock {
45 55
 	dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
46 56
 		dispatch_group_t group = dispatch_group_create();