Browse Source

Refactored modals and added tests (#3955)

Yogev Ben David 6 years ago
parent
commit
0984d047f6
No account linked to committer's email address

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

204
 	[self assertReady];
204
 	[self assertReady];
205
 	
205
 	
206
 	UIViewController<RNNRootViewProtocol> *newVc = [_controllerFactory createLayoutAndSaveToStore:layout];
206
 	UIViewController<RNNRootViewProtocol> *newVc = [_controllerFactory createLayoutAndSaveToStore:layout];
207
-	[_modalManager showModal:newVc animated:newVc.getLeafViewController.options.animations.showModal.enable completion:^(NSString *componentId) {
208
-		[_eventEmitter sendOnNavigationCommandCompletion:showModal params:@{@"layout": layout}];
209
-		completion(componentId);
207
+	
208
+	if ([newVc respondsToSelector:@selector(applyModalOptions)]) {
209
+		[newVc.getLeafViewController applyModalOptions];
210
+	}
211
+	
212
+	[newVc.getLeafViewController waitForReactViewRender:newVc.getLeafViewController.options.animations.showModal.waitForRender perform:^{
213
+		[_modalManager showModal:newVc animated:newVc.getLeafViewController.options.animations.showModal.enable hasCustomAnimation:newVc.getLeafViewController.options.animations.showModal.hasCustomAnimation completion:^(NSString *componentId) {
214
+			[_eventEmitter sendOnNavigationCommandCompletion:showModal params:@{@"layout": layout}];
215
+			completion(componentId);
216
+		}];
210
 	}];
217
 	}];
211
 }
218
 }
212
 
219
 

+ 2
- 2
lib/ios/RNNModalManager.h View File

11
 
11
 
12
 @interface RNNModalManager : NSObject
12
 @interface RNNModalManager : NSObject
13
 
13
 
14
-@property (nonatomic, strong) UIViewController<RNNRootViewProtocol>* toVC;
15
 @property (nonatomic, weak) id<RNNModalManagerDelegate> delegate;
14
 @property (nonatomic, weak) id<RNNModalManagerDelegate> delegate;
16
 
15
 
17
-- (void)showModal:(UIViewController*)viewController animated:(BOOL)animated completion:(RNNTransitionWithComponentIdCompletionBlock)completion;
16
+- (void)showModal:(UIViewController *)viewController animated:(BOOL)animated completion:(RNNTransitionWithComponentIdCompletionBlock)completion;
17
+- (void)showModal:(UIViewController *)viewController animated:(BOOL)animated hasCustomAnimation:(BOOL)hasCustomAnimation completion:(RNNTransitionWithComponentIdCompletionBlock)completion;
18
 - (void)dismissModal:(UIViewController *)viewController completion:(RNNTransitionCompletionBlock)completion;
18
 - (void)dismissModal:(UIViewController *)viewController completion:(RNNTransitionCompletionBlock)completion;
19
 - (void)dismissAllModalsAnimated:(BOOL)animated;
19
 - (void)dismissAllModalsAnimated:(BOOL)animated;
20
 
20
 

+ 15
- 36
lib/ios/RNNModalManager.m View File

2
 #import "RNNRootViewController.h"
2
 #import "RNNRootViewController.h"
3
 
3
 
4
 @implementation RNNModalManager {
4
 @implementation RNNModalManager {
5
-	RNNTransitionWithComponentIdCompletionBlock _completionBlock;
6
 	NSMutableArray* _pendingModalIdsToDismiss;
5
 	NSMutableArray* _pendingModalIdsToDismiss;
7
 	NSMutableArray* _presentedModals;
6
 	NSMutableArray* _presentedModals;
8
 }
7
 }
16
 	return self;
15
 	return self;
17
 }
16
 }
18
 
17
 
19
--(void)showModal:(BOOL)animated {
18
+-(void)showModal:(UIViewController *)viewController animated:(BOOL)animated completion:(RNNTransitionWithComponentIdCompletionBlock)completion {
19
+	[self showModal:viewController animated:animated hasCustomAnimation:NO completion:completion];
20
+}
21
+
22
+-(void)showModal:(UIViewController *)viewController animated:(BOOL)animated hasCustomAnimation:(BOOL)hasCustomAnimation completion:(RNNTransitionWithComponentIdCompletionBlock)completion {
23
+	if (!viewController) {
24
+		@throw [NSException exceptionWithName:@"ShowUnknownModal" reason:@"showModal called with nil viewController" userInfo:nil];
25
+	}
26
+	
20
 	UIViewController* topVC = [self topPresentedVC];
27
 	UIViewController* topVC = [self topPresentedVC];
21
 	topVC.definesPresentationContext = YES;
28
 	topVC.definesPresentationContext = YES;
22
 	
29
 	
23
-	if ([topVC conformsToProtocol:@protocol(RNNRootViewProtocol)]) {
24
-		UIViewController<RNNRootViewProtocol> *navigationTopVC = (UIViewController<RNNRootViewProtocol>*)topVC;
25
-		RNNNavigationOptions* options = navigationTopVC.getLeafViewController.options;
26
-		if (options.animations.showModal.hasCustomAnimation) {
27
-			self.toVC.transitioningDelegate = navigationTopVC;
28
-		}
30
+	if (hasCustomAnimation) {
31
+		viewController.transitioningDelegate = (UIViewController<UIViewControllerTransitioningDelegate>*)topVC;
29
 	}
32
 	}
30
 	
33
 	
31
-	[topVC presentViewController:self.toVC animated:animated completion:^{
32
-		if (_completionBlock) {
33
-			_completionBlock(self.toVC.getLeafViewController.componentId);
34
-			_completionBlock = nil;
34
+	[topVC presentViewController:viewController animated:animated completion:^{
35
+		if (completion) {
36
+			completion(nil);
35
 		}
37
 		}
36
 		
38
 		
37
-		[_presentedModals addObject:self.toVC.navigationController ? self.toVC.navigationController : self.toVC];
38
-		
39
-		self.toVC = nil;
39
+		[_presentedModals addObject:viewController.navigationController ? viewController.navigationController : viewController];
40
 	}];
40
 	}];
41
 }
41
 }
42
 
42
 
43
--(void)showModal:(UIViewController *)viewController animated:(BOOL)animated completion:(RNNTransitionWithComponentIdCompletionBlock)completion {
44
-	self.toVC = (UIViewController<RNNRootViewProtocol>*)viewController;
45
-	RNNNavigationOptions* options = self.toVC.getLeafViewController.options;
46
-
47
-	_completionBlock = completion;
48
-	
49
-    if ([self.toVC respondsToSelector:@selector(applyModalOptions)]) {
50
-        [self.toVC.getLeafViewController applyModalOptions];
51
-    }
52
-    
53
-    if ([self.toVC respondsToSelector:@selector(isCustomViewController)] &&
54
-        [self.toVC.getLeafViewController isCustomViewController]
55
-    ) {
56
-		[self showModal:animated];
57
-	} else {
58
-		[self.toVC.getLeafViewController waitForReactViewRender:options.animations.showModal.waitForRender perform:^{
59
-			[self showModal:animated];
60
-		}];
61
-	}
62
-}
63
-
64
 - (void)dismissModal:(UIViewController *)viewController completion:(RNNTransitionCompletionBlock)completion {
43
 - (void)dismissModal:(UIViewController *)viewController completion:(RNNTransitionCompletionBlock)completion {
65
 	if (viewController) {
44
 	if (viewController) {
66
 		[_pendingModalIdsToDismiss addObject:viewController];
45
 		[_pendingModalIdsToDismiss addObject:viewController];

+ 1
- 1
lib/ios/RNNRootViewController.m View File

89
 }
89
 }
90
 
90
 
91
 - (void)waitForReactViewRender:(BOOL)wait perform:(RNNReactViewReadyCompletionBlock)readyBlock {
91
 - (void)waitForReactViewRender:(BOOL)wait perform:(RNNReactViewReadyCompletionBlock)readyBlock {
92
-	if (wait) {
92
+	if (wait && !_isExternalComponent) {
93
 		[self onReactViewReady:readyBlock];
93
 		[self onReactViewReady:readyBlock];
94
 	} else {
94
 	} else {
95
 		readyBlock();
95
 		readyBlock();

+ 16
- 6
lib/ios/ReactNativeNavigationTests/RNNModalManagerTest.m View File

2
 #import "RNNModalManager.h"
2
 #import "RNNModalManager.h"
3
 
3
 
4
 @interface MockViewController : UIViewController
4
 @interface MockViewController : UIViewController
5
+
6
+@property CGFloat presentViewControllerCalls;
7
+
5
 @end
8
 @end
6
 @implementation MockViewController
9
 @implementation MockViewController
7
 
10
 
8
 - (void)presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion {
11
 - (void)presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion {
12
+	_presentViewControllerCalls++;
9
 	completion();
13
 	completion();
10
 }
14
 }
11
 
15
 
12
 @end
16
 @end
13
 
17
 
14
 @interface MockModalManager : RNNModalManager
18
 @interface MockModalManager : RNNModalManager
19
+@property (nonatomic, strong) MockViewController* topPresentedVC;
15
 @end
20
 @end
16
-@implementation MockModalManager
17
-
18
--(UIViewController*)topPresentedVC {
19
-	MockViewController* vc = [MockViewController new];
20
-	return vc;
21
-}
22
 
21
 
22
+@implementation MockModalManager
23
 @end
23
 @end
24
 
24
 
25
 @interface RNNModalManagerTest : XCTestCase <RNNModalManagerDelegate> {
25
 @interface RNNModalManagerTest : XCTestCase <RNNModalManagerDelegate> {
41
 	_vc2 = [RNNRootViewController new];
41
 	_vc2 = [RNNRootViewController new];
42
 	_vc3 = [RNNRootViewController new];
42
 	_vc3 = [RNNRootViewController new];
43
 	_modalManager = [[MockModalManager alloc] init];
43
 	_modalManager = [[MockModalManager alloc] init];
44
+	_modalManager.topPresentedVC = [MockViewController new];
44
 }
45
 }
46
+
45
 - (void)testDismissMultipleModalsInvokeDelegateWithCorrectParameters {
47
 - (void)testDismissMultipleModalsInvokeDelegateWithCorrectParameters {
46
 	[_modalManager showModal:_vc1 animated:NO completion:nil];
48
 	[_modalManager showModal:_vc1 animated:NO completion:nil];
47
 	[_modalManager showModal:_vc2 animated:NO completion:nil];
49
 	[_modalManager showModal:_vc2 animated:NO completion:nil];
95
 	XCTAssertTrue(_modalDismissedCount == 0);
97
 	XCTAssertTrue(_modalDismissedCount == 0);
96
 }
98
 }
97
 
99
 
100
+- (void)testShowModal_NilModalThrows {
101
+	XCTAssertThrows([_modalManager showModal:nil animated:NO completion:nil]);
102
+}
103
+
104
+- (void)testShowModal_CallPresentViewController {
105
+	[_modalManager showModal:_vc1 animated:NO completion:nil];
106
+	XCTAssertTrue(_modalManager.topPresentedVC.presentViewControllerCalls == 1);
107
+}
98
 
108
 
99
 #pragma mark RNNModalManagerDelegate
109
 #pragma mark RNNModalManagerDelegate
100
 
110