Browse Source

Fixes unnecessary rendering of the last viewController in setStackRoot (#5358)

* Fixes unnecessary rendering of the last viewController in setStackRoot, Closes #5355

* Add setStackRoot unit tests
Yogev Ben David 5 years ago
parent
commit
4cc6b56e44

+ 3
- 1
lib/ios/RNNCommandsHandler.m View File

@@ -173,7 +173,9 @@ static NSString* const setDefaultOptions	= @"setDefaultOptions";
173 173
 	
174 174
 	NSArray<UIViewController *> *childViewControllers = [_controllerFactory createChildrenLayout:children];
175 175
 	for (UIViewController<RNNLayoutProtocol>* viewController in childViewControllers) {
176
-		[viewController renderTreeAndWait:NO perform:nil];
176
+		if (![viewController isEqual:childViewControllers.lastObject]) {
177
+			[viewController renderTreeAndWait:NO perform:nil];
178
+		}
177 179
 	}
178 180
 	UIViewController *newVC = childViewControllers.lastObject;
179 181
 	UIViewController *fromVC = [RNNLayoutManager findComponentForId:componentId];

+ 46
- 8
lib/ios/ReactNativeNavigationTests/RNNCommandsHandlerTest.m View File

@@ -120,20 +120,20 @@
120 120
 	initialOptions.topBar.title.text = [[Text alloc] initWithValue:@"the title"];
121 121
 	RNNLayoutInfo* layoutInfo = [RNNLayoutInfo new];
122 122
 	RNNTestRootViewCreator* creator = [[RNNTestRootViewCreator alloc] init];
123
-
123
+	
124 124
 	RNNViewControllerPresenter* presenter = [[RNNViewControllerPresenter alloc] init];
125 125
 	RNNRootViewController* vc = [[RNNRootViewController alloc] initWithLayoutInfo:layoutInfo rootViewCreator:creator eventEmitter:nil presenter:presenter options:initialOptions defaultOptions:nil];
126
-
126
+	
127 127
 	RNNNavigationController* nav = [[RNNNavigationController alloc] initWithLayoutInfo:nil creator:creator options:[[RNNNavigationOptions alloc] initEmptyOptions] defaultOptions:nil presenter:[[RNNNavigationControllerPresenter alloc] init] eventEmitter:nil childViewControllers:@[vc]];
128 128
 	
129 129
 	[vc viewWillAppear:false];
130 130
 	XCTAssertTrue([vc.navigationItem.title isEqual:@"the title"]);
131
-
131
+	
132 132
 	[self.uut setReadyToReceiveCommands:true];
133
-
133
+	
134 134
 	NSDictionary* dictFromJs = @{@"topBar": @{@"background" : @{@"color" : @(0xFFFF0000)}}};
135 135
 	UIColor* expectedColor = [UIColor colorWithRed:1 green:0 blue:0 alpha:1];
136
-
136
+	
137 137
 	[self.uut mergeOptions:@"componentId" options:dictFromJs completion:^{
138 138
 		XCTAssertTrue([vc.navigationItem.title isEqual:@"the title"]);
139 139
 		XCTAssertTrue([nav.navigationBar.barTintColor isEqual:expectedColor]);
@@ -193,7 +193,7 @@
193 193
 - (void)testShowOverlay_invokeNavigationCommandEventWithLayout {
194 194
 	[self.uut setReadyToReceiveCommands:true];
195 195
 	OCMStub([self.overlayManager showOverlayWindow:[OCMArg any]]);
196
-	id mockedVC = [OCMockObject partialMockForObject:self.vc1];	
196
+	id mockedVC = [OCMockObject partialMockForObject:self.vc1];
197 197
 	OCMStub([self.controllerFactory createLayout:[OCMArg any]]).andReturn(mockedVC);
198 198
 	
199 199
 	NSDictionary* layout = @{};
@@ -216,10 +216,10 @@
216 216
 	[self.uut setReadyToReceiveCommands:true];
217 217
 	NSString* componentId = @"componentId";
218 218
 	UIViewController* returnedView = [UIViewController new];
219
-
219
+	
220 220
 	id classMock = OCMClassMock([RNNLayoutManager class]);
221 221
 	OCMStub(ClassMethod([classMock findComponentForId:componentId])).andReturn(returnedView);
222
-
222
+	
223 223
 	[[self.overlayManager expect] dismissOverlay:returnedView];
224 224
 	[self.uut dismissOverlay:componentId commandId:@"" completion:^{} rejection:^(NSString *code, NSString *message, NSError *error) {}];
225 225
 	[self.overlayManager verify];
@@ -289,6 +289,44 @@
289 289
 	XCTAssertTrue([_nvc.viewControllers isEqual:newViewControllers]);
290 290
 }
291 291
 
292
+- (void)testSetStackRoot_callRenderTreeAndWaitOnce {
293
+	id vc1Mock = OCMPartialMock(_vc1);
294
+	id vc2Mock = OCMPartialMock(_vc2);
295
+	NSArray* newViewControllers = @[vc1Mock, vc2Mock];
296
+	id classMock = OCMClassMock([RNNLayoutManager class]);
297
+	OCMStub(ClassMethod([classMock findComponentForId:@"vc1"])).andReturn(_nvc);
298
+	OCMStub([self.controllerFactory createChildrenLayout:[OCMArg any]]).andReturn(newViewControllers);
299
+	[self.uut setReadyToReceiveCommands:true];
300
+	[self.uut setStackRoot:@"vc1" commandId:@"" children:nil completion:^{
301
+		
302
+	} rejection:^(NSString *code, NSString *message, NSError *error) {
303
+		
304
+	}];
305
+	
306
+	[[vc1Mock expect] renderTreeAndWait:NO perform:[OCMArg any]];
307
+	[[vc2Mock expect] renderTreeAndWait:NO perform:[OCMArg any]];
308
+}
309
+
310
+- (void)testSetStackRoot_waitForRender {
311
+	_vc2.options.animations.setStackRoot.waitForRender = [[Bool alloc] initWithBOOL:YES];
312
+	id vc1Mock = OCMPartialMock(_vc1);
313
+	id vc2Mock = OCMPartialMock(_vc2);
314
+	OCMStub([vc2Mock renderTreeAndWait:YES perform:[OCMArg any]]);
315
+	NSArray* newViewControllers = @[vc1Mock, vc2Mock];
316
+	id classMock = OCMClassMock([RNNLayoutManager class]);
317
+	OCMStub(ClassMethod([classMock findComponentForId:@"vc1"])).andReturn(_nvc);
318
+	OCMStub([self.controllerFactory createChildrenLayout:[OCMArg any]]).andReturn(newViewControllers);
319
+	[self.uut setReadyToReceiveCommands:true];
320
+	[self.uut setStackRoot:@"vc1" commandId:@"" children:nil completion:^{
321
+		
322
+	} rejection:^(NSString *code, NSString *message, NSError *error) {
323
+		
324
+	}];
325
+	
326
+	[[vc1Mock expect] renderTreeAndWait:NO perform:[OCMArg any]];
327
+	[[vc2Mock expect] renderTreeAndWait:YES perform:[OCMArg any]];
328
+}
329
+
292 330
 - (void)testSetRoot_waitForRenderTrue {
293 331
 	[self.uut setReadyToReceiveCommands:true];
294 332
 	self.vc1.options = [[RNNNavigationOptions alloc] initEmptyOptions];