Browse Source

Fix split view on iOS (#5961)

* Fix split view on iOS

* Fix units

* Remove stackManager
Yogev Ben David 4 years ago
parent
commit
c8c925abb0
No account linked to committer's email address

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

@@ -94,7 +94,7 @@
94 94
 	_componentRegistry = [[RNNReactComponentRegistry alloc] initWithCreator:rootViewCreator];
95 95
 	RNNControllerFactory *controllerFactory = [[RNNControllerFactory alloc] initWithRootViewCreator:rootViewCreator eventEmitter:eventEmitter store:_store componentRegistry:_componentRegistry andBridge:bridge bottomTabsAttachModeFactory:[BottomTabsAttachModeFactory new]];
96 96
 
97
-	_commandsHandler = [[RNNCommandsHandler alloc] initWithControllerFactory:controllerFactory eventEmitter:eventEmitter stackManager:[RNNNavigationStackManager new] modalManager:_modalManager overlayManager:_overlayManager mainWindow:_mainWindow];
97
+	_commandsHandler = [[RNNCommandsHandler alloc] initWithControllerFactory:controllerFactory eventEmitter:eventEmitter modalManager:_modalManager overlayManager:_overlayManager mainWindow:_mainWindow];
98 98
 	RNNBridgeModule *bridgeModule = [[RNNBridgeModule alloc] initWithCommandsHandler:_commandsHandler];
99 99
 
100 100
 	return [@[bridgeModule,eventEmitter] arrayByAddingObjectsFromArray:[self extraModulesFromDelegate]];

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

@@ -1,14 +1,12 @@
1 1
 #import <Foundation/Foundation.h>
2 2
 #import <UIKit/UIKit.h>
3
-
4 3
 #import "RNNControllerFactory.h"
5 4
 #import "RNNModalManager.h"
6
-#import "RNNNavigationStackManager.h"
7 5
 #import "RNNOverlayManager.h"
8 6
 
9 7
 @interface RNNCommandsHandler : NSObject
10 8
 
11
-- (instancetype)initWithControllerFactory:(RNNControllerFactory*)controllerFactory eventEmitter:(RNNEventEmitter *)eventEmitter stackManager:(RNNNavigationStackManager *)stackManager modalManager:(RNNModalManager *)modalManager overlayManager:(RNNOverlayManager *)overlayManager mainWindow:(UIWindow *)mainWindow;
9
+- (instancetype)initWithControllerFactory:(RNNControllerFactory*)controllerFactory eventEmitter:(RNNEventEmitter *)eventEmitter modalManager:(RNNModalManager *)modalManager overlayManager:(RNNOverlayManager *)overlayManager mainWindow:(UIWindow *)mainWindow;
12 10
 
13 11
 @property (nonatomic) BOOL readyToReceiveCommands;
14 12
 

+ 7
- 8
lib/ios/RNNCommandsHandler.m View File

@@ -7,6 +7,7 @@
7 7
 #import "UIViewController+LayoutProtocol.h"
8 8
 #import "RNNLayoutManager.h"
9 9
 #import "UIViewController+Utils.h"
10
+#import "UINavigationController+RNNCommands.h"
10 11
 #import "RNNAssert.h"
11 12
 
12 13
 static NSString* const setRoot	= @"setRoot";
@@ -32,18 +33,16 @@ static NSString* const setDefaultOptions	= @"setDefaultOptions";
32 33
 	RNNControllerFactory *_controllerFactory;
33 34
 	RNNModalManager* _modalManager;
34 35
 	RNNOverlayManager* _overlayManager;
35
-	RNNNavigationStackManager* _stackManager;
36 36
 	RNNEventEmitter* _eventEmitter;
37 37
 	UIWindow* _mainWindow;
38 38
 }
39 39
 
40
-- (instancetype)initWithControllerFactory:(RNNControllerFactory*)controllerFactory eventEmitter:(RNNEventEmitter *)eventEmitter stackManager:(RNNNavigationStackManager *)stackManager modalManager:(RNNModalManager *)modalManager overlayManager:(RNNOverlayManager *)overlayManager mainWindow:(UIWindow *)mainWindow {
40
+- (instancetype)initWithControllerFactory:(RNNControllerFactory*)controllerFactory eventEmitter:(RNNEventEmitter *)eventEmitter  modalManager:(RNNModalManager *)modalManager overlayManager:(RNNOverlayManager *)overlayManager mainWindow:(UIWindow *)mainWindow {
41 41
 	self = [super init];
42 42
 	_controllerFactory = controllerFactory;
43 43
 	_eventEmitter = eventEmitter;
44 44
 	_modalManager = modalManager;
45 45
 	_modalManager.delegate = self;
46
-	_stackManager = stackManager;
47 46
 	_overlayManager = overlayManager;
48 47
 	_mainWindow = mainWindow;
49 48
 	return self;
@@ -162,7 +161,7 @@ static NSString* const setDefaultOptions	= @"setDefaultOptions";
162 161
 	} else {
163 162
         newVc.waitForRender = newVc.resolveOptionsWithDefault.animations.push.shouldWaitForRender;
164 163
         [newVc setReactViewReadyCallback:^{
165
-            [self->_stackManager push:newVc onTop:fromVC animated:[newVc.resolveOptionsWithDefault.animations.push.enable getWithDefaultValue:YES] completion:^{
164
+            [fromVC.stack push:newVc onTop:fromVC animated:[newVc.resolveOptionsWithDefault.animations.push.enable getWithDefaultValue:YES] completion:^{
166 165
                 [self->_eventEmitter sendOnNavigationCommandCompletion:push commandId:commandId params:@{@"componentId": componentId}];
167 166
                 completion();
168 167
             } rejection:rejection];
@@ -189,7 +188,7 @@ static NSString* const setDefaultOptions	= @"setDefaultOptions";
189 188
 
190 189
     newVC.waitForRender = ([options.animations.setStackRoot.waitForRender getWithDefaultValue:NO]);
191 190
     [newVC setReactViewReadyCallback:^{
192
-        [self->_stackManager setStackChildren:childViewControllers fromViewController:fromVC animated:[options.animations.setStackRoot.enable getWithDefaultValue:YES] completion:^{
191
+        [fromVC.stack setStackChildren:childViewControllers fromViewController:fromVC animated:[options.animations.setStackRoot.enable getWithDefaultValue:YES] completion:^{
193 192
             [weakEventEmitter sendOnNavigationCommandCompletion:setStackRoot commandId:commandId params:@{@"componentId": componentId}];
194 193
             completion();
195 194
         } rejection:rejection];
@@ -206,7 +205,7 @@ static NSString* const setDefaultOptions	= @"setDefaultOptions";
206 205
 	RNNNavigationOptions *options = [[RNNNavigationOptions alloc] initWithDict:mergeOptions];
207 206
 	[vc overrideOptions:options];
208 207
 	
209
-	[_stackManager pop:vc animated:[vc.resolveOptionsWithDefault.animations.pop.enable getWithDefaultValue:YES] completion:^{
208
+	[vc.stack pop:vc animated:[vc.resolveOptionsWithDefault.animations.pop.enable getWithDefaultValue:YES] completion:^{
210 209
 		[_eventEmitter sendOnNavigationCommandCompletion:pop commandId:commandId params:@{@"componentId": componentId}];
211 210
 		completion();
212 211
 	} rejection:rejection];
@@ -220,7 +219,7 @@ static NSString* const setDefaultOptions	= @"setDefaultOptions";
220 219
 	RNNNavigationOptions *options = [[RNNNavigationOptions alloc] initWithDict:mergeOptions];
221 220
 	[vc overrideOptions:options];
222 221
 	
223
-	[_stackManager popTo:vc animated:[vc.resolveOptionsWithDefault.animations.pop.enable getWithDefaultValue:YES] completion:^(NSArray *poppedViewControllers) {
222
+	[vc.stack popTo:vc animated:[vc.resolveOptionsWithDefault.animations.pop.enable getWithDefaultValue:YES] completion:^(NSArray *poppedViewControllers) {
224 223
 		[_eventEmitter sendOnNavigationCommandCompletion:popTo commandId:commandId params:@{@"componentId": componentId}];
225 224
 		completion();
226 225
 	} rejection:rejection];
@@ -240,7 +239,7 @@ static NSString* const setDefaultOptions	= @"setDefaultOptions";
240 239
 		completion();
241 240
 	}];
242 241
 	
243
-	[_stackManager popToRoot:vc animated:[vc.resolveOptionsWithDefault.animations.pop.enable getWithDefaultValue:YES] completion:^(NSArray *poppedViewControllers) {
242
+	[vc.stack popToRoot:vc animated:[vc.resolveOptionsWithDefault.animations.pop.enable getWithDefaultValue:YES] completion:^(NSArray *poppedViewControllers) {
244 243
 		
245 244
 	} rejection:^(NSString *code, NSString *message, NSError *error) {
246 245
 		

+ 0
- 99
lib/ios/RNNNavigationStackManager.m View File

@@ -1,99 +0,0 @@
1
-#import "RNNNavigationStackManager.h"
2
-#import "RNNErrorHandler.h"
3
-#import <React/RCTI18nUtil.h>
4
-
5
-typedef void (^RNNAnimationBlock)(void);
6
-
7
-@implementation RNNNavigationStackManager
8
-
9
-- (void)push:(UIViewController *)newTop onTop:(UIViewController *)onTopViewController animated:(BOOL)animated completion:(RNNTransitionCompletionBlock)completion rejection:(RCTPromiseRejectBlock)rejection {
10
-	UINavigationController *nvc = onTopViewController.navigationController;
11
-
12
-	if([[RCTI18nUtil sharedInstance] isRTL]) {
13
-		nvc.view.semanticContentAttribute = UISemanticContentAttributeForceRightToLeft;
14
-		nvc.navigationBar.semanticContentAttribute = UISemanticContentAttributeForceRightToLeft;
15
-	} else {
16
-		nvc.view.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight;
17
-		nvc.navigationBar.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight;
18
-	}
19
-	
20
-	[self performAnimationBlock:^{
21
-		[nvc pushViewController:newTop animated:animated];
22
-	} completion:completion];
23
-}
24
-
25
-- (void)pop:(UIViewController *)viewController animated:(BOOL)animated completion:(RNNTransitionCompletionBlock)completion rejection:(RNNTransitionRejectionBlock)rejection {
26
-    UINavigationController *nvc = viewController.navigationController;
27
-    if ([nvc.viewControllers indexOfObject:viewController] < 0) {
28
-        [RNNErrorHandler reject:rejection withErrorCode:1012 errorDescription:@"popping component failed"];
29
-        return;
30
-    }
31
-    
32
-    if ([nvc topViewController] != viewController) {
33
-        NSMutableArray * vcs = nvc.viewControllers.mutableCopy;
34
-        [vcs removeObject:viewController];
35
-        [self performAnimationBlock:^{
36
-            [nvc setViewControllers:vcs animated:animated];
37
-        } completion:^{
38
-            completion();
39
-        }];
40
-    } else {
41
-        [self performAnimationBlock:^{
42
-            [viewController.navigationController popViewControllerAnimated:animated];
43
-        } completion:^{
44
-            completion();
45
-        }];
46
-    }
47
-}
48
-
49
-- (void)popTo:(UIViewController *)viewController animated:(BOOL)animated completion:(RNNPopCompletionBlock)completion rejection:(RNNTransitionRejectionBlock)rejection; {
50
-	__block NSArray* poppedVCs;
51
-	
52
-	if ([viewController.navigationController.childViewControllers containsObject:viewController]) {
53
-		[self performAnimationBlock:^{
54
-			poppedVCs = [viewController.navigationController popToViewController:viewController animated:animated];
55
-		} completion:^{
56
-			if (completion) {
57
-				completion(poppedVCs);
58
-			}
59
-		}];
60
-	} else {
61
-		[RNNErrorHandler reject:rejection withErrorCode:1011 errorDescription:@"component not found in stack"];
62
-	}
63
-}
64
-
65
-- (void)popToRoot:(UIViewController*)viewController animated:(BOOL)animated completion:(RNNPopCompletionBlock)completion rejection:(RNNTransitionRejectionBlock)rejection {
66
-	__block NSArray* poppedVCs;
67
-	
68
-	[self performAnimationBlock:^{
69
-		poppedVCs = [viewController.navigationController popToRootViewControllerAnimated:animated];
70
-	} completion:^{
71
-		completion(poppedVCs);
72
-	}];
73
-}
74
-
75
-- (void)setStackChildren:(NSArray<UIViewController *> *)children fromViewController:(UIViewController *)fromViewController animated:(BOOL)animated completion:(RNNTransitionCompletionBlock)completion rejection:(RNNTransitionRejectionBlock)rejection {
76
-	UINavigationController* nvc = fromViewController.navigationController;
77
-	
78
-	[self performAnimationBlock:^{
79
-		[nvc setViewControllers:children animated:animated];
80
-	} completion:completion];
81
-}
82
-
83
-# pragma mark Private
84
-
85
-- (void)performAnimationBlock:(RNNAnimationBlock)animationBlock completion:(RNNTransitionCompletionBlock)completion {
86
-	[CATransaction begin];
87
-	[CATransaction setCompletionBlock:^{
88
-		if (completion) {
89
-			completion();
90
-		}
91
-	}];
92
-	
93
-	animationBlock();
94
-	
95
-	[CATransaction commit];
96
-}
97
-
98
-
99
-@end

+ 0
- 2
lib/ios/RNNSplitViewController.h View File

@@ -5,6 +5,4 @@
5 5
 
6 6
 @interface RNNSplitViewController : UISplitViewController <RNNLayoutProtocol>
7 7
 
8
-- (void)bindChildViewControllers:(NSArray<UIViewController<RNNLayoutProtocol> *> *)viewControllers;
9
-
10 8
 @end

+ 4
- 4
lib/ios/RNNSplitViewController.m View File

@@ -3,10 +3,10 @@
3 3
 
4 4
 @implementation RNNSplitViewController
5 5
 
6
-- (void)bindChildViewControllers:(NSArray<UIViewController<RNNLayoutProtocol> *> *)viewControllers {
7
-	[self setViewControllers:viewControllers];
8
-	UIViewController<UISplitViewControllerDelegate>* masterViewController = viewControllers[0];
9
-	self.delegate = masterViewController;
6
+- (void)setViewControllers:(NSArray<__kindof UIViewController *> *)viewControllers {
7
+    [super setViewControllers:viewControllers];
8
+    UIViewController<UISplitViewControllerDelegate>* masterViewController = viewControllers[0];
9
+    self.delegate = masterViewController;
10 10
 }
11 11
 
12 12
 -(void)viewWillAppear:(BOOL)animated{

+ 1
- 0
lib/ios/RNNStackController.h View File

@@ -1,6 +1,7 @@
1 1
 #import <UIKit/UIKit.h>
2 2
 #import "RNNStackPresenter.h"
3 3
 #import "UINavigationController+RNNOptions.h"
4
+#import "UINavigationController+RNNCommands.h"
4 5
 #import "UIViewController+LayoutProtocol.h"
5 6
 
6 7
 @interface RNNStackController : UINavigationController <RNNLayoutProtocol>

+ 0
- 4
lib/ios/RNNStackController.m View File

@@ -32,10 +32,6 @@
32 32
     [self.parentViewController mergeChildOptions:options child:child];
33 33
 }
34 34
 
35
-- (UINavigationController *)navigationController {
36
-	return self;
37
-}
38
-
39 35
 - (UIStatusBarStyle)preferredStatusBarStyle {
40 36
 	return [_presenter getStatusBarStyle:self.resolveOptions];
41 37
 }

+ 8
- 7
lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj View File

@@ -13,8 +13,6 @@
13 13
 		21B85E5F1F44482A00B314B5 /* RNNNavigationButtons.h in Headers */ = {isa = PBXBuildFile; fileRef = 21B85E5E1F44482A00B314B5 /* RNNNavigationButtons.h */; };
14 14
 		261F0E641E6EC94900989DE2 /* RNNModalManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 261F0E621E6EC94900989DE2 /* RNNModalManager.h */; };
15 15
 		261F0E651E6EC94900989DE2 /* RNNModalManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 261F0E631E6EC94900989DE2 /* RNNModalManager.m */; };
16
-		261F0E6A1E6F028A00989DE2 /* RNNNavigationStackManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 261F0E681E6F028A00989DE2 /* RNNNavigationStackManager.h */; };
17
-		261F0E6B1E6F028A00989DE2 /* RNNNavigationStackManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 261F0E691E6F028A00989DE2 /* RNNNavigationStackManager.m */; };
18 16
 		263905AE1E4C6F440023D7D3 /* MMDrawerBarButtonItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 2639058A1E4C6F440023D7D3 /* MMDrawerBarButtonItem.h */; };
19 17
 		263905AF1E4C6F440023D7D3 /* MMDrawerBarButtonItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 2639058B1E4C6F440023D7D3 /* MMDrawerBarButtonItem.m */; };
20 18
 		263905B01E4C6F440023D7D3 /* MMDrawerController+Subclass.h in Headers */ = {isa = PBXBuildFile; fileRef = 2639058C1E4C6F440023D7D3 /* MMDrawerController+Subclass.h */; };
@@ -327,6 +325,8 @@
327 325
 		50CED44E239EA78700C42EE2 /* TopBarAppearancePresenter.m in Sources */ = {isa = PBXBuildFile; fileRef = 50CED44C239EA78700C42EE2 /* TopBarAppearancePresenter.m */; };
328 326
 		50CED451239F9DFC00C42EE2 /* TopBarPresenter.h in Headers */ = {isa = PBXBuildFile; fileRef = 50CED44F239F9DFC00C42EE2 /* TopBarPresenter.h */; };
329 327
 		50CED452239F9DFC00C42EE2 /* TopBarPresenter.m in Sources */ = {isa = PBXBuildFile; fileRef = 50CED450239F9DFC00C42EE2 /* TopBarPresenter.m */; };
328
+		50CF23392405668C0098042D /* UINavigationController+RNNCommands.h in Headers */ = {isa = PBXBuildFile; fileRef = 50CF23372405668C0098042D /* UINavigationController+RNNCommands.h */; };
329
+		50CF233A2405668C0098042D /* UINavigationController+RNNCommands.m in Sources */ = {isa = PBXBuildFile; fileRef = 50CF23382405668C0098042D /* UINavigationController+RNNCommands.m */; };
330 330
 		50D031342005149000386B3D /* RNNOverlayManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 50D031322005149000386B3D /* RNNOverlayManager.h */; };
331 331
 		50D031352005149000386B3D /* RNNOverlayManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 50D031332005149000386B3D /* RNNOverlayManager.m */; };
332 332
 		50D3A36E23B8D6C600717F95 /* SharedElementTransitionsCreator.h in Headers */ = {isa = PBXBuildFile; fileRef = 50D3A36C23B8D6C600717F95 /* SharedElementTransitionsCreator.h */; };
@@ -488,8 +488,6 @@
488 488
 		21B85E5E1F44482A00B314B5 /* RNNNavigationButtons.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNNavigationButtons.h; sourceTree = "<group>"; };
489 489
 		261F0E621E6EC94900989DE2 /* RNNModalManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNNModalManager.h; sourceTree = "<group>"; };
490 490
 		261F0E631E6EC94900989DE2 /* RNNModalManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNNModalManager.m; sourceTree = "<group>"; };
491
-		261F0E681E6F028A00989DE2 /* RNNNavigationStackManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNNNavigationStackManager.h; sourceTree = "<group>"; };
492
-		261F0E691E6F028A00989DE2 /* RNNNavigationStackManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNNNavigationStackManager.m; sourceTree = "<group>"; };
493 491
 		2639058A1E4C6F440023D7D3 /* MMDrawerBarButtonItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MMDrawerBarButtonItem.h; sourceTree = "<group>"; };
494 492
 		2639058B1E4C6F440023D7D3 /* MMDrawerBarButtonItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MMDrawerBarButtonItem.m; sourceTree = "<group>"; };
495 493
 		2639058C1E4C6F440023D7D3 /* MMDrawerController+Subclass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MMDrawerController+Subclass.h"; sourceTree = "<group>"; };
@@ -809,6 +807,8 @@
809 807
 		50CED44C239EA78700C42EE2 /* TopBarAppearancePresenter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TopBarAppearancePresenter.m; sourceTree = "<group>"; };
810 808
 		50CED44F239F9DFC00C42EE2 /* TopBarPresenter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TopBarPresenter.h; sourceTree = "<group>"; };
811 809
 		50CED450239F9DFC00C42EE2 /* TopBarPresenter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TopBarPresenter.m; sourceTree = "<group>"; };
810
+		50CF23372405668C0098042D /* UINavigationController+RNNCommands.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UINavigationController+RNNCommands.h"; sourceTree = "<group>"; };
811
+		50CF23382405668C0098042D /* UINavigationController+RNNCommands.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UINavigationController+RNNCommands.m"; sourceTree = "<group>"; };
812 812
 		50D031322005149000386B3D /* RNNOverlayManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNOverlayManager.h; sourceTree = "<group>"; };
813 813
 		50D031332005149000386B3D /* RNNOverlayManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNOverlayManager.m; sourceTree = "<group>"; };
814 814
 		50D3A36C23B8D6C600717F95 /* SharedElementTransitionsCreator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SharedElementTransitionsCreator.h; sourceTree = "<group>"; };
@@ -1425,8 +1425,6 @@
1425 1425
 			children = (
1426 1426
 				261F0E621E6EC94900989DE2 /* RNNModalManager.h */,
1427 1427
 				261F0E631E6EC94900989DE2 /* RNNModalManager.m */,
1428
-				261F0E681E6F028A00989DE2 /* RNNNavigationStackManager.h */,
1429
-				261F0E691E6F028A00989DE2 /* RNNNavigationStackManager.m */,
1430 1428
 				50D031322005149000386B3D /* RNNOverlayManager.h */,
1431 1429
 				50D031332005149000386B3D /* RNNOverlayManager.m */,
1432 1430
 				5050465221F8F4490035497A /* RNNReactComponentRegistry.h */,
@@ -1578,6 +1576,8 @@
1578 1576
 				5038A3B0216DF41B009280BC /* UIViewController+RNNOptions.m */,
1579 1577
 				5038A3B3216DF602009280BC /* UINavigationController+RNNOptions.h */,
1580 1578
 				5038A3B4216DF602009280BC /* UINavigationController+RNNOptions.m */,
1579
+				50CF23372405668C0098042D /* UINavigationController+RNNCommands.h */,
1580
+				50CF23382405668C0098042D /* UINavigationController+RNNCommands.m */,
1581 1581
 				5038A3B7216DFCFD009280BC /* UITabBarController+RNNOptions.h */,
1582 1582
 				5038A3B8216DFCFD009280BC /* UITabBarController+RNNOptions.m */,
1583 1583
 				651E1F8821FD611600DFEA19 /* UISplitViewController+RNNOptions.h */,
@@ -1809,6 +1809,7 @@
1809 1809
 				5048862D20BE976D000908DE /* RNNLayoutOptions.h in Headers */,
1810 1810
 				50BCB29123F2C7CD00D6C8E5 /* AnchorTransition.h in Headers */,
1811 1811
 				5038A374216CDDB6009280BC /* UIViewController+SideMenuController.h in Headers */,
1812
+				50CF23392405668C0098042D /* UINavigationController+RNNCommands.h in Headers */,
1812 1813
 				E8A5CD621F49114F00E89D0D /* RNNElement.h in Headers */,
1813 1814
 				50CED449239EA56100C42EE2 /* TopBarPresenterCreator.h in Headers */,
1814 1815
 				5012240E21735999000F5F98 /* RNNBasePresenter.h in Headers */,
@@ -2024,7 +2025,6 @@
2024 2025
 				E8A5CD531F464F0400E89D0D /* StackTransitionDelegate.m in Sources */,
2025 2026
 				50CB3B6A1FDE911400AA153B /* RNNSideMenuOptions.m in Sources */,
2026 2027
 				503A8A0623BB850A0094D1C4 /* TimeInterval.m in Sources */,
2027
-				261F0E6B1E6F028A00989DE2 /* RNNNavigationStackManager.m in Sources */,
2028 2028
 				5016E8F020209690009D4F7C /* RNNCustomTitleView.m in Sources */,
2029 2029
 				5061B6C823D48449008B9827 /* VerticalRotationTransition.m in Sources */,
2030 2030
 				5022EDB62405224B00852BA6 /* BottomTabPresenter.m in Sources */,
@@ -2043,6 +2043,7 @@
2043 2043
 				5022EDC624054C6100852BA6 /* BottomTabsAppearancePresenter.m in Sources */,
2044 2044
 				7B1126A01E2D263F00F9B03B /* RNNEventEmitter.m in Sources */,
2045 2045
 				A7626BFD1FC2FB2C00492FB8 /* RNNTopBarOptions.m in Sources */,
2046
+				50CF233A2405668C0098042D /* UINavigationController+RNNCommands.m in Sources */,
2046 2047
 				5050465521F8F4490035497A /* RNNReactComponentRegistry.m in Sources */,
2047 2048
 				509416AC23A11CB20036092C /* NullEnum.m in Sources */,
2048 2049
 				503A8A1A23BCB2ED0094D1C4 /* RNNReactButtonView.m in Sources */,

lib/ios/RNNNavigationStackManager.h → lib/ios/UINavigationController+RNNCommands.h View File

@@ -1,11 +1,11 @@
1
-#import <Foundation/Foundation.h>
2 1
 #import <UIKit/UIKit.h>
3 2
 
4 3
 typedef void (^RNNTransitionCompletionBlock)(void);
5 4
 typedef void (^RNNPopCompletionBlock)(NSArray* poppedViewControllers);
6 5
 typedef void (^RNNTransitionRejectionBlock)(NSString *code, NSString *message, NSError *error);
7 6
 
8
-@interface RNNNavigationStackManager : NSObject
7
+
8
+@interface UINavigationController (RNNCommands)
9 9
 
10 10
 - (void)push:(UIViewController *)newTop onTop:(UIViewController *)onTopViewController animated:(BOOL)animated completion:(RNNTransitionCompletionBlock)completion rejection:(RNNTransitionRejectionBlock)rejection;
11 11
 
@@ -17,4 +17,5 @@ typedef void (^RNNTransitionRejectionBlock)(NSString *code, NSString *message, N
17 17
 
18 18
 - (void)setStackChildren:(NSArray<UIViewController *> *)children fromViewController:(UIViewController *)fromViewController animated:(BOOL)animated completion:(RNNTransitionCompletionBlock)completion rejection:(RNNTransitionRejectionBlock)rejection;
19 19
 
20
+
20 21
 @end

+ 91
- 0
lib/ios/UINavigationController+RNNCommands.m View File

@@ -0,0 +1,91 @@
1
+#import "UINavigationController+RNNCommands.h"
2
+#import "RNNErrorHandler.h"
3
+#import <React/RCTI18nUtil.h>
4
+
5
+typedef void (^RNNAnimationBlock)(void);
6
+
7
+@implementation UINavigationController (RNNCommands)
8
+
9
+- (void)push:(UIViewController *)newTop onTop:(UIViewController *)onTopViewController animated:(BOOL)animated completion:(RNNTransitionCompletionBlock)completion rejection:(RCTPromiseRejectBlock)rejection {
10
+    if([[RCTI18nUtil sharedInstance] isRTL]) {
11
+        self.view.semanticContentAttribute = UISemanticContentAttributeForceRightToLeft;
12
+        self.navigationBar.semanticContentAttribute = UISemanticContentAttributeForceRightToLeft;
13
+    } else {
14
+        self.view.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight;
15
+        self.navigationBar.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight;
16
+    }
17
+    
18
+    [self performAnimationBlock:^{
19
+        [self pushViewController:newTop animated:animated];
20
+    } completion:completion];
21
+}
22
+
23
+- (void)pop:(UIViewController *)viewController animated:(BOOL)animated completion:(RNNTransitionCompletionBlock)completion rejection:(RNNTransitionRejectionBlock)rejection {
24
+    if ([self.viewControllers indexOfObject:viewController] < 0) {
25
+        [RNNErrorHandler reject:rejection withErrorCode:1012 errorDescription:@"popping component failed"];
26
+        return;
27
+    }
28
+    
29
+    if ([self topViewController] != viewController) {
30
+        NSMutableArray * vcs = self.viewControllers.mutableCopy;
31
+        [vcs removeObject:viewController];
32
+        [self performAnimationBlock:^{
33
+            [self setViewControllers:vcs animated:animated];
34
+        } completion:^{
35
+            completion();
36
+        }];
37
+    } else {
38
+        [self performAnimationBlock:^{
39
+            [self popViewControllerAnimated:animated];
40
+        } completion:^{
41
+            completion();
42
+        }];
43
+    }
44
+}
45
+
46
+- (void)popTo:(UIViewController *)viewController animated:(BOOL)animated completion:(RNNPopCompletionBlock)completion rejection:(RNNTransitionRejectionBlock)rejection; {
47
+    __block NSArray* poppedVCs;
48
+    if ([self.childViewControllers containsObject:viewController]) {
49
+        [self performAnimationBlock:^{
50
+            poppedVCs = [self popToViewController:viewController animated:animated];
51
+        } completion:^{
52
+            if (completion) {
53
+                completion(poppedVCs);
54
+            }
55
+        }];
56
+    } else {
57
+        [RNNErrorHandler reject:rejection withErrorCode:1011 errorDescription:@"component not found in stack"];
58
+    }
59
+}
60
+
61
+- (void)popToRoot:(UIViewController*)viewController animated:(BOOL)animated completion:(RNNPopCompletionBlock)completion rejection:(RNNTransitionRejectionBlock)rejection {
62
+    __block NSArray* poppedVCs;
63
+    [self performAnimationBlock:^{
64
+        poppedVCs = [self popToRootViewControllerAnimated:animated];
65
+    } completion:^{
66
+        completion(poppedVCs);
67
+    }];
68
+}
69
+
70
+- (void)setStackChildren:(NSArray<UIViewController *> *)children fromViewController:(UIViewController *)fromViewController animated:(BOOL)animated completion:(RNNTransitionCompletionBlock)completion rejection:(RNNTransitionRejectionBlock)rejection {
71
+    [self performAnimationBlock:^{
72
+        [self setViewControllers:children animated:animated];
73
+    } completion:completion];
74
+}
75
+
76
+# pragma mark Private
77
+
78
+- (void)performAnimationBlock:(RNNAnimationBlock)animationBlock completion:(RNNTransitionCompletionBlock)completion {
79
+    [CATransaction begin];
80
+    [CATransaction setCompletionBlock:^{
81
+        if (completion) {
82
+            completion();
83
+        }
84
+    }];
85
+    
86
+    animationBlock();
87
+    
88
+    [CATransaction commit];
89
+}
90
+
91
+@end

+ 2
- 0
lib/ios/UIViewController+LayoutProtocol.h View File

@@ -18,6 +18,8 @@ typedef void (^RNNReactViewReadyCompletionBlock)(void);
18 18
 
19 19
 - (void)mergeChildOptions:(RNNNavigationOptions *)options child:(UIViewController *)child;
20 20
 
21
+- (UINavigationController *)stack;
22
+
21 23
 - (RNNNavigationOptions *)resolveOptions;
22 24
 
23 25
 - (RNNNavigationOptions *)resolveOptionsWithDefault;

+ 8
- 0
lib/ios/UIViewController+LayoutProtocol.m View File

@@ -60,6 +60,14 @@
60 60
 	return interfaceOrientationMask;
61 61
 }
62 62
 
63
+- (UINavigationController *)stack {
64
+    if ([self isKindOfClass:UINavigationController.class]) {
65
+        return (UINavigationController *)self;
66
+    } else {
67
+        return self.navigationController;
68
+    }
69
+}
70
+
63 71
 - (void)render {
64 72
     if (!self.waitForRender) {
65 73
         [self readyForPresentation];

+ 2
- 2
playground/ios/NavigationTests/RNNCommandsHandlerTest.m View File

@@ -69,7 +69,7 @@
69 69
 	self.overlayManager = [OCMockObject partialMockForObject:[RNNOverlayManager new]];
70 70
 	self.modalManager = [OCMockObject partialMockForObject:[RNNModalManager new]];
71 71
 	self.controllerFactory = [OCMockObject partialMockForObject:[[RNNControllerFactory alloc] initWithRootViewCreator:nil eventEmitter:self.eventEmmiter store:nil componentRegistry:nil andBridge:nil bottomTabsAttachModeFactory:[BottomTabsAttachModeFactory new]]];
72
-	self.uut = [[RNNCommandsHandler alloc] initWithControllerFactory:self.controllerFactory eventEmitter:self.eventEmmiter stackManager:[RNNNavigationStackManager new] modalManager:self.modalManager overlayManager:self.overlayManager mainWindow:_mainWindow];
72
+	self.uut = [[RNNCommandsHandler alloc] initWithControllerFactory:self.controllerFactory eventEmitter:self.eventEmmiter modalManager:self.modalManager overlayManager:self.overlayManager mainWindow:_mainWindow];
73 73
 	self.vc1 = [self generateComponentWithComponentId:@"1"];
74 74
 	self.vc2 = [self generateComponentWithComponentId:@"2"];
75 75
 	self.vc3 = [self generateComponentWithComponentId:@"3"];
@@ -98,7 +98,7 @@
98 98
 - (NSArray*)getPublicMethodNamesForObject:(NSObject*)obj {
99 99
 	NSMutableArray* skipMethods = [NSMutableArray new];
100 100
 	
101
-	[skipMethods addObject:@"initWithControllerFactory:eventEmitter:stackManager:modalManager:overlayManager:mainWindow:"];
101
+	[skipMethods addObject:@"initWithControllerFactory:eventEmitter:modalManager:overlayManager:mainWindow:"];
102 102
 	[skipMethods addObject:@"assertReady"];
103 103
 	[skipMethods addObject:@"setReadyToReceiveCommands:"];
104 104
 	[skipMethods addObject:@"readyToReceiveCommands"];

+ 4
- 7
playground/ios/NavigationTests/RNNNavigationStackManagerTest.m View File

@@ -1,5 +1,4 @@
1 1
 #import <XCTest/XCTest.h>
2
-#import "RNNNavigationStackManager.h"
3 2
 #import "RNNComponentViewController.h"
4 3
 #import "RNNStackController.h"
5 4
 
@@ -9,7 +8,6 @@
9 8
 @property (nonatomic, strong) UIViewController *vc1;
10 9
 @property (nonatomic, strong) UIViewController *vc2;
11 10
 @property (nonatomic, strong) UIViewController *vc3;
12
-@property (nonatomic, strong) RNNNavigationStackManager *stackManager;
13 11
 
14 12
 @end
15 13
 
@@ -22,7 +20,6 @@
22 20
 	self.vc1 = [RNNComponentViewController new];
23 21
 	self.vc2 = [RNNComponentViewController new];
24 22
 	self.vc3 = [RNNComponentViewController new];
25
-	self.stackManager = [RNNNavigationStackManager new];
26 23
 	
27 24
 	NSArray *vcArray = @[self.vc1, self.vc2, self.vc3];
28 25
 	[self.nvc setViewControllers:vcArray];
@@ -32,7 +29,7 @@
32 29
 - (void)testPop_removeTopVCFromStack {
33 30
 	XCTestExpectation *expectation = [self expectationWithDescription:@"Testing Async Method"];
34 31
 	XCTAssertTrue([self.nvc.topViewController isEqual:self.vc3]);
35
-	[_stackManager popTo:self.vc2 animated:YES completion:^(NSArray *poppedViewControllers) {
32
+	[_nvc popTo:self.vc2 animated:YES completion:^(NSArray *poppedViewControllers) {
36 33
 		XCTAssertTrue([self.nvc.topViewController isEqual:self.vc2]);
37 34
 		[expectation fulfill];
38 35
 	} rejection:nil];
@@ -43,7 +40,7 @@
43 40
 - (void)testPopToSpecificVC_removeAllPopedVCFromStack {
44 41
 	XCTestExpectation *expectation = [self expectationWithDescription:@"Testing Async Method"];
45 42
 	XCTAssertFalse([self.nvc.topViewController isEqual:self.vc1]);
46
-	[_stackManager popTo:self.vc1 animated:NO completion:^(NSArray *poppedViewControllers) {
43
+	[_nvc popTo:self.vc1 animated:NO completion:^(NSArray *poppedViewControllers) {
47 44
 		XCTAssertTrue([self.nvc.topViewController isEqual:self.vc1]);
48 45
 		[expectation fulfill];
49 46
 	} rejection:nil];
@@ -53,7 +50,7 @@
53 50
 
54 51
 - (void)testPopToRoot_removeAllTopVCsFromStack {
55 52
 	XCTestExpectation *expectation = [self expectationWithDescription:@"Testing Async Method"];
56
-	[_stackManager popToRoot:self.vc3 animated:NO completion:^(NSArray *poppedViewControllers) {
53
+	[_nvc popToRoot:self.vc3 animated:NO completion:^(NSArray *poppedViewControllers) {
57 54
 		XCTAssertTrue(self.nvc.childViewControllers.count == 1);
58 55
 		XCTAssertTrue([self.nvc.topViewController isEqual:self.vc1]);
59 56
 		[expectation fulfill];
@@ -64,7 +61,7 @@
64 61
 
65 62
 - (void)testStackRoot_shouldUpdateNavigationControllerChildrenViewControllers {
66 63
 	XCTestExpectation *expectation = [self expectationWithDescription:@"Testing Async Method"];
67
-	[_stackManager setStackChildren:@[self.vc2] fromViewController:self.vc1 animated:NO completion:^{
64
+	[_nvc setStackChildren:@[self.vc2] fromViewController:self.vc1 animated:NO completion:^{
68 65
 		XCTAssertTrue(self.nvc.childViewControllers.count == 1);
69 66
 		XCTAssertTrue([self.nvc.topViewController isEqual:self.vc2]);
70 67
 		[expectation fulfill];