Browse Source

Fixes overlays level - #4145 (#4264)

* Fixes overlays level - #4145

* Disable overlay unmounts when dismissed

* Fixes e2e
Yogev Ben David 6 years ago
parent
commit
e09831e65a
No account linked to committer's email address

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

58
 	
58
 	
59
 	UIViewController *vc = [_controllerFactory createLayout:layout[@"root"] saveToStore:_store];
59
 	UIViewController *vc = [_controllerFactory createLayout:layout[@"root"] saveToStore:_store];
60
 	
60
 	
61
-	UIApplication.sharedApplication.delegate.window.rootViewController = vc;
62
-	[UIApplication.sharedApplication.delegate.window makeKeyWindow];
61
+	[UIApplication sharedApplication].windows.firstObject.rootViewController = vc;
62
+
63
 	[_eventEmitter sendOnNavigationCommandCompletion:setRoot params:@{@"layout": layout}];
63
 	[_eventEmitter sendOnNavigationCommandCompletion:setRoot params:@{@"layout": layout}];
64
 	completion();
64
 	completion();
65
 }
65
 }
279
 	[self assertReady];
279
 	[self assertReady];
280
 	
280
 	
281
 	UIViewController<RNNParentProtocol>* overlayVC = [_controllerFactory createLayout:layout saveToStore:_store];
281
 	UIViewController<RNNParentProtocol>* overlayVC = [_controllerFactory createLayout:layout saveToStore:_store];
282
-	[_overlayManager showOverlay:overlayVC];
282
+	UIWindow* overlayWindow = [[RNNOverlayWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
283
+	overlayWindow.rootViewController = overlayVC;
284
+	[_overlayManager showOverlayWindow:overlayWindow];
283
 	[_eventEmitter sendOnNavigationCommandCompletion:showOverlay params:@{@"layout": layout}];
285
 	[_eventEmitter sendOnNavigationCommandCompletion:showOverlay params:@{@"layout": layout}];
284
 	completion();
286
 	completion();
285
 }
287
 }

+ 1
- 1
lib/ios/RNNOverlayManager.h View File

5
 
5
 
6
 @interface RNNOverlayManager : NSObject
6
 @interface RNNOverlayManager : NSObject
7
 
7
 
8
-- (void)showOverlay:(UIViewController*)viewController;
8
+- (void)showOverlayWindow:(UIWindow*)viewController;
9
 - (void)dismissOverlay:(UIViewController*)viewController;
9
 - (void)dismissOverlay:(UIViewController*)viewController;
10
 
10
 
11
 @property (nonatomic, retain) NSMutableArray* overlayWindows;
11
 @property (nonatomic, retain) NSMutableArray* overlayWindows;

+ 8
- 8
lib/ios/RNNOverlayManager.m View File

11
 
11
 
12
 #pragma mark - public
12
 #pragma mark - public
13
 
13
 
14
-- (void)showOverlay:(UIViewController *)viewController {
15
-	UIWindow* overlayWindow = [[RNNOverlayWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
14
+- (void)showOverlayWindow:(RNNOverlayWindow *)overlayWindow {
15
+	overlayWindow.previousWindow = [UIApplication sharedApplication].keyWindow;
16
 	[_overlayWindows addObject:overlayWindow];
16
 	[_overlayWindows addObject:overlayWindow];
17
-	viewController.view.backgroundColor = [UIColor clearColor];
17
+	overlayWindow.rootViewController.view.backgroundColor = [UIColor clearColor];
18
 	[overlayWindow setWindowLevel:UIWindowLevelNormal];
18
 	[overlayWindow setWindowLevel:UIWindowLevelNormal];
19
-	[overlayWindow setRootViewController:viewController];
20
-	[overlayWindow setHidden:NO];
19
+	[overlayWindow makeKeyAndVisible];
21
 }
20
 }
22
 
21
 
23
 - (void)dismissOverlay:(UIViewController*)viewController {
22
 - (void)dismissOverlay:(UIViewController*)viewController {
24
-	UIWindow* overlayWindow = [self findWindowByRootViewController:viewController];
23
+	RNNOverlayWindow* overlayWindow = [self findWindowByRootViewController:viewController];
24
+	[overlayWindow.previousWindow makeKeyWindow];
25
 	[self detachOverlayWindow:overlayWindow];
25
 	[self detachOverlayWindow:overlayWindow];
26
 }
26
 }
27
 
27
 
33
 	[_overlayWindows removeObject:overlayWindow];
33
 	[_overlayWindows removeObject:overlayWindow];
34
 }
34
 }
35
 
35
 
36
-- (UIWindow *)findWindowByRootViewController:(UIViewController *)viewController {
37
-	for (UIWindow* window in _overlayWindows) {
36
+- (RNNOverlayWindow *)findWindowByRootViewController:(UIViewController *)viewController {
37
+	for (RNNOverlayWindow* window in _overlayWindows) {
38
 		if ([window.rootViewController isEqual:viewController]) {
38
 		if ([window.rootViewController isEqual:viewController]) {
39
 			return window;
39
 			return window;
40
 		}
40
 		}

+ 1
- 1
lib/ios/RNNOverlayWindow.h View File

1
 #import <UIKit/UIKit.h>
1
 #import <UIKit/UIKit.h>
2
 
2
 
3
 @interface RNNOverlayWindow : UIWindow
3
 @interface RNNOverlayWindow : UIWindow
4
-
4
+@property (nonatomic, weak) UIWindow* previousWindow;
5
 @end
5
 @end

+ 4
- 4
lib/ios/ReactNativeNavigationTests/RNNCommandsHandlerTest.m View File

192
 
192
 
193
 - (void)testShowOverlay_createLayout {
193
 - (void)testShowOverlay_createLayout {
194
 	[self.store setReadyToReceiveCommands:true];
194
 	[self.store setReadyToReceiveCommands:true];
195
-	OCMStub([self.overlayManager showOverlay:[OCMArg any]]);
195
+	OCMStub([self.overlayManager showOverlayWindow:[OCMArg any]]);
196
 	NSDictionary* layout = @{};
196
 	NSDictionary* layout = @{};
197
 	
197
 	
198
 	[[self.controllerFactory expect] createLayout:layout saveToStore:self.store];
198
 	[[self.controllerFactory expect] createLayout:layout saveToStore:self.store];
202
 
202
 
203
 - (void)testShowOverlay_saveToStore {
203
 - (void)testShowOverlay_saveToStore {
204
 	[self.store setReadyToReceiveCommands:true];
204
 	[self.store setReadyToReceiveCommands:true];
205
-	OCMStub([self.overlayManager showOverlay:[OCMArg any]]);
205
+	OCMStub([self.overlayManager showOverlayWindow:[OCMArg any]]);
206
 	OCMStub([self.controllerFactory createLayout:[OCMArg any] saveToStore:[OCMArg any]]);
206
 	OCMStub([self.controllerFactory createLayout:[OCMArg any] saveToStore:[OCMArg any]]);
207
 	
207
 	
208
 	[[self.controllerFactory expect] createLayout:[OCMArg any] saveToStore:self.store];
208
 	[[self.controllerFactory expect] createLayout:[OCMArg any] saveToStore:self.store];
215
 	UIViewController* layoutVC = [RNNRootViewController new];
215
 	UIViewController* layoutVC = [RNNRootViewController new];
216
 	OCMStub([self.controllerFactory createLayout:[OCMArg any] saveToStore:[OCMArg any]]).andReturn(layoutVC);
216
 	OCMStub([self.controllerFactory createLayout:[OCMArg any] saveToStore:[OCMArg any]]).andReturn(layoutVC);
217
 	
217
 	
218
-	[[self.overlayManager expect] showOverlay:layoutVC];
218
+	[[self.overlayManager expect] showOverlayWindow:[OCMArg any]];
219
 	[self.uut showOverlay:@{} completion:^{}];
219
 	[self.uut showOverlay:@{} completion:^{}];
220
 	[self.overlayManager verify];
220
 	[self.overlayManager verify];
221
 }
221
 }
222
 
222
 
223
 - (void)testShowOverlay_invokeNavigationCommandEventWithLayout {
223
 - (void)testShowOverlay_invokeNavigationCommandEventWithLayout {
224
 	[self.store setReadyToReceiveCommands:true];
224
 	[self.store setReadyToReceiveCommands:true];
225
-	OCMStub([self.overlayManager showOverlay:[OCMArg any]]);
225
+	OCMStub([self.overlayManager showOverlayWindow:[OCMArg any]]);
226
 	OCMStub([self.controllerFactory createLayout:[OCMArg any] saveToStore:[OCMArg any]]);
226
 	OCMStub([self.controllerFactory createLayout:[OCMArg any] saveToStore:[OCMArg any]]);
227
 
227
 
228
 	NSDictionary* layout = @{};
228
 	NSDictionary* layout = @{};

+ 16
- 17
lib/ios/ReactNativeNavigationTests/RNNOverlayManagerTest.m View File

1
 #import <XCTest/XCTest.h>
1
 #import <XCTest/XCTest.h>
2
+#import <OCMock/OCMock.h>
2
 #import "RNNOverlayManager.h"
3
 #import "RNNOverlayManager.h"
3
 
4
 
4
 @interface RNNOverlayManagerTest : XCTestCase
5
 @interface RNNOverlayManagerTest : XCTestCase
5
 
6
 
6
 @property (nonatomic, retain) RNNOverlayManager* overlayManager;
7
 @property (nonatomic, retain) RNNOverlayManager* overlayManager;
7
 @property (nonatomic, retain) UIViewController* overlayVC;
8
 @property (nonatomic, retain) UIViewController* overlayVC;
9
+@property (nonatomic, retain) RNNOverlayWindow* overlayWindow;
8
 
10
 
9
 @end
11
 @end
10
 
12
 
14
     [super setUp];
16
     [super setUp];
15
 	_overlayManager = [RNNOverlayManager new];
17
 	_overlayManager = [RNNOverlayManager new];
16
 	_overlayVC = [UIViewController new];
18
 	_overlayVC = [UIViewController new];
19
+	_overlayWindow = [OCMockObject partialMockForObject:[RNNOverlayWindow new]];
20
+	OCMStub([_overlayWindow makeKeyAndVisible]);
21
+	_overlayWindow.rootViewController = _overlayVC;
17
 }
22
 }
18
 
23
 
19
 
24
 
20
 - (void)testShowOverlayShouldAddWindowWithVCAsRoot {
25
 - (void)testShowOverlayShouldAddWindowWithVCAsRoot {
21
-	[_overlayManager showOverlay:_overlayVC];
26
+	[_overlayManager showOverlayWindow:_overlayWindow];
22
 	UIWindow* window = _overlayManager.overlayWindows.lastObject;
27
 	UIWindow* window = _overlayManager.overlayWindows.lastObject;
23
 	XCTAssertTrue([window.rootViewController isEqual:_overlayVC]);
28
 	XCTAssertTrue([window.rootViewController isEqual:_overlayVC]);
24
 }
29
 }
25
 
30
 
26
-- (void)testShowOverlayShouldAddVisibleWindow {
27
-	[_overlayManager showOverlay:_overlayVC];
28
-	UIWindow* window = _overlayManager.overlayWindows.lastObject;
29
-	XCTAssertTrue(window.windowLevel == UIWindowLevelNormal);
30
-	XCTAssertFalse(window.hidden);
31
+- (void)testShowOverlayShouldSetKeyAndVisibleWindow {
32
+	id window = _overlayManager.overlayWindows.lastObject;
33
+	[[window expect] makeKeyAndVisible];
34
+	[_overlayManager showOverlayWindow:_overlayWindow];
35
+	[window verify];
31
 }
36
 }
32
 
37
 
33
 - (void)testShowOverlayShouldCreateTransparentView {
38
 - (void)testShowOverlayShouldCreateTransparentView {
34
-	[_overlayManager showOverlay:_overlayVC];
39
+	[_overlayManager showOverlayWindow:_overlayWindow];
35
 	UIWindow* window = _overlayManager.overlayWindows.lastObject;
40
 	UIWindow* window = _overlayManager.overlayWindows.lastObject;
36
 	XCTAssertTrue(window.rootViewController.view.backgroundColor == [UIColor clearColor]);
41
 	XCTAssertTrue(window.rootViewController.view.backgroundColor == [UIColor clearColor]);
37
 }
42
 }
38
 
43
 
39
-- (void)testShowOverlayShouldNotBeKeyWindow {
40
-	[_overlayManager showOverlay:_overlayVC];
41
-	UIWindow* window = _overlayManager.overlayWindows.lastObject;
42
-	XCTAssertFalse(window.keyWindow);
43
-}
44
-
45
 - (void)testDismissOverlayShouldCleanWindowRootVC {
44
 - (void)testDismissOverlayShouldCleanWindowRootVC {
46
-	[_overlayManager showOverlay:_overlayVC];
45
+	[_overlayManager showOverlayWindow:_overlayWindow];
47
 	UIWindow* window = _overlayManager.overlayWindows.lastObject;
46
 	UIWindow* window = _overlayManager.overlayWindows.lastObject;
48
 	[_overlayManager dismissOverlay:_overlayVC];
47
 	[_overlayManager dismissOverlay:_overlayVC];
49
 	XCTAssertNil(window.rootViewController);
48
 	XCTAssertNil(window.rootViewController);
50
 }
49
 }
51
 
50
 
52
 - (void)testDismissOverlayShouldHideWindow {
51
 - (void)testDismissOverlayShouldHideWindow {
53
-	[_overlayManager showOverlay:_overlayVC];
52
+	[_overlayManager showOverlayWindow:_overlayWindow];
54
 	UIWindow* window = _overlayManager.overlayWindows.lastObject;
53
 	UIWindow* window = _overlayManager.overlayWindows.lastObject;
55
 	[_overlayManager dismissOverlay:_overlayVC];
54
 	[_overlayManager dismissOverlay:_overlayVC];
56
 	XCTAssertTrue(window.hidden);
55
 	XCTAssertTrue(window.hidden);
57
 }
56
 }
58
 
57
 
59
 - (void)testDismissOverlayShouldRemoveOverlayWindow {
58
 - (void)testDismissOverlayShouldRemoveOverlayWindow {
60
-	[_overlayManager showOverlay:_overlayVC];
59
+	[_overlayManager showOverlayWindow:_overlayWindow];
61
 	UIWindow* window = _overlayManager.overlayWindows.lastObject;
60
 	UIWindow* window = _overlayManager.overlayWindows.lastObject;
62
 	[_overlayManager dismissOverlay:_overlayVC];
61
 	[_overlayManager dismissOverlay:_overlayVC];
63
 	XCTAssertFalse([_overlayManager.overlayWindows containsObject:window]);
62
 	XCTAssertFalse([_overlayManager.overlayWindows containsObject:window]);
64
 }
63
 }
65
 
64
 
66
 - (void)testDismissOverlayShouldNotRemoveWrongVC {
65
 - (void)testDismissOverlayShouldNotRemoveWrongVC {
67
-	[_overlayManager showOverlay:_overlayVC];
66
+	[_overlayManager showOverlayWindow:_overlayWindow];
68
 	UIWindow* window = _overlayManager.overlayWindows.lastObject;
67
 	UIWindow* window = _overlayManager.overlayWindows.lastObject;
69
 	[_overlayManager dismissOverlay:[UIViewController new]];
68
 	[_overlayManager dismissOverlay:[UIViewController new]];
70
 	XCTAssertTrue([_overlayManager.overlayWindows containsObject:window]);
69
 	XCTAssertTrue([_overlayManager.overlayWindows containsObject:window]);

+ 10
- 1
package.json View File

128
     "test-runner": "jest",
128
     "test-runner": "jest",
129
     "specs": "e2e",
129
     "specs": "e2e",
130
     "configurations": {
130
     "configurations": {
131
+      "ios.none": {
132
+        "binaryPath": "playground/ios/DerivedData/playground/Build/Products/Debug-iphonesimulator/playground.app",
133
+        "type": "ios.none",
134
+        "name": "iPhone X",
135
+        "session": {
136
+          "server": "ws://localhost:8099",
137
+          "sessionId": "playground"
138
+        }
139
+      },
131
       "ios.sim.debug": {
140
       "ios.sim.debug": {
132
         "binaryPath": "playground/ios/DerivedData/playground/Build/Products/Debug-iphonesimulator/playground.app",
141
         "binaryPath": "playground/ios/DerivedData/playground/Build/Products/Debug-iphonesimulator/playground.app",
133
         "build": "RCT_NO_LAUNCH_PACKAGER=true xcodebuild build -scheme playground -project playground/ios/playground.xcodeproj -sdk iphonesimulator -configuration Debug -derivedDataPath playground/ios/DerivedData/playground ONLY_ACTIVE_ARCH=YES -quiet",
142
         "build": "RCT_NO_LAUNCH_PACKAGER=true xcodebuild build -scheme playground -project playground/ios/playground.xcodeproj -sdk iphonesimulator -configuration Debug -derivedDataPath playground/ios/DerivedData/playground ONLY_ACTIVE_ARCH=YES -quiet",
154
       }
163
       }
155
     }
164
     }
156
   }
165
   }
157
-}
166
+}