|
@@ -1,122 +1,64 @@
|
1
|
1
|
#import "RNNNavigationStackManager.h"
|
2
|
|
-#import "RNNRootViewController.h"
|
3
|
|
-#import "RNNAnimator.h"
|
4
|
2
|
#import "RNNErrorHandler.h"
|
5
|
|
-#import "RNNNavigationController.h"
|
6
|
3
|
|
7
|
|
-dispatch_queue_t RCTGetUIManagerQueue(void);
|
8
|
|
-@interface RNNNavigationStackManager()
|
9
|
|
-@property (nonatomic, strong) RNNNavigationController* nvc;
|
10
|
|
-@property (nonatomic, strong) RNNRootViewController* toVC;
|
11
|
|
-@end
|
|
4
|
+typedef void (^RNNAnimationBlock)(void);
|
12
|
5
|
|
13
|
|
-@implementation RNNNavigationStackManager {
|
14
|
|
- RNNStore *_store;
|
15
|
|
- RNNTransitionCompletionBlock _completionBlock;
|
16
|
|
-}
|
|
6
|
+@implementation RNNNavigationStackManager
|
17
|
7
|
|
18
|
|
--(instancetype)initWithStore:(RNNStore*)store {
|
19
|
|
- self = [super init];
|
20
|
|
- _store = store;
|
21
|
|
- return self;
|
22
|
|
-}
|
|
8
|
+- (void)push:(UIViewController *)newTop onTop:(UIViewController *)onTopViewController animated:(BOOL)animated animationDelegate:(id)animationDelegate completion:(RNNTransitionCompletionBlock)completion rejection:(RCTPromiseRejectBlock)rejection {
|
|
9
|
+ UINavigationController *nvc = onTopViewController.navigationController;
|
23
|
10
|
|
24
|
|
--(void)push:(UIViewController<RNNRootViewProtocol> *)newTop onTop:(NSString *)componentId completion:(RNNTransitionCompletionBlock)completion rejection:(RCTPromiseRejectBlock)rejection {
|
25
|
|
- RNNNavigationController *nvc = [self getComponentStack:componentId];
|
26
|
|
- [self assertNavigationControllerExist:nvc reject:rejection];
|
27
|
|
- [self preparePush:newTop onTopVC:nvc completion:completion];
|
28
|
|
- if ([newTop isCustomViewController]) {
|
29
|
|
- [self pushAfterLoad:nil];
|
30
|
|
- } else {
|
31
|
|
- [self waitForContentToAppearAndThen:@selector(pushAfterLoad:)];
|
32
|
|
- }
|
33
|
|
-}
|
34
|
|
-
|
35
|
|
--(void)preparePush:(UIViewController<RNNRootViewProtocol> *)newTop onTopVC:(RNNNavigationController*)nvc completion:(RNNTransitionCompletionBlock)completion {
|
36
|
|
- self.toVC = (RNNRootViewController*)newTop;
|
37
|
|
- self.nvc = nvc;
|
38
|
|
-
|
39
|
|
-
|
40
|
|
- if (self.toVC.options.animations.push.hasCustomAnimation || self.toVC.isCustomTransitioned) {
|
41
|
|
- nvc.delegate = newTop;
|
|
11
|
+ if (animationDelegate) {
|
|
12
|
+ nvc.delegate = animationDelegate;
|
42
|
13
|
} else {
|
43
|
14
|
nvc.delegate = nil;
|
44
|
15
|
nvc.interactivePopGestureRecognizer.delegate = nil;
|
45
|
16
|
}
|
46
|
17
|
|
47
|
|
- _completionBlock = completion;
|
|
18
|
+ [self performAnimationBlock:^{
|
|
19
|
+ [nvc pushViewController:newTop animated:animated];
|
|
20
|
+ } completion:completion];
|
48
|
21
|
}
|
49
|
22
|
|
50
|
|
--(void)waitForContentToAppearAndThen:(SEL)nameOfSelector {
|
51
|
|
- [[NSNotificationCenter defaultCenter] addObserver:self
|
52
|
|
- selector:nameOfSelector
|
53
|
|
- name: @"RCTContentDidAppearNotification"
|
54
|
|
- object:nil];
|
|
23
|
+- (void)pop:(UIViewController *)viewController animated:(BOOL)animated completion:(RNNTransitionCompletionBlock)completion rejection:(RNNTransitionRejectionBlock)rejection {
|
|
24
|
+ [self performAnimationBlock:^{
|
|
25
|
+ [viewController.navigationController popViewControllerAnimated:animated];
|
|
26
|
+ } completion:completion];
|
55
|
27
|
}
|
56
|
28
|
|
57
|
|
--(void)pushAfterLoad:(NSDictionary*)notif {
|
58
|
|
- [[NSNotificationCenter defaultCenter] removeObserver:self name:@"RCTContentDidAppearNotification" object:nil];
|
59
|
|
- [CATransaction begin];
|
60
|
|
- [CATransaction setCompletionBlock:^{
|
61
|
|
- if (_completionBlock) {
|
62
|
|
- _completionBlock();
|
63
|
|
- _completionBlock = nil;
|
|
29
|
+- (void)popTo:(UIViewController *)viewController animated:(BOOL)animated completion:(RNNPopCompletionBlock)completion rejection:(RNNTransitionRejectionBlock)rejection; {
|
|
30
|
+ __block NSArray* poppedVCs;
|
|
31
|
+
|
|
32
|
+ [self performAnimationBlock:^{
|
|
33
|
+ poppedVCs = [viewController.navigationController popToViewController:viewController animated:animated];
|
|
34
|
+ } completion:^{
|
|
35
|
+ if (completion) {
|
|
36
|
+ completion(poppedVCs);
|
64
|
37
|
}
|
65
|
38
|
}];
|
66
|
|
-
|
67
|
|
- [self.nvc pushViewController:self.toVC animated:self.toVC.options.animations.push.enable];
|
68
|
|
- [CATransaction commit];
|
69
|
|
-
|
70
|
|
- self.toVC = nil;
|
71
|
|
- self.nvc.interactivePopGestureRecognizer.delegate = nil;
|
72
|
|
- self.nvc = nil;
|
73
|
39
|
}
|
74
|
40
|
|
75
|
|
--(void)pop:(NSString *)componentId withTransitionOptions:(RNNAnimationOptions *)transitionOptions rejection:(RCTPromiseRejectBlock)rejection {
|
76
|
|
- RNNRootViewController* vc = (RNNRootViewController*)[_store findComponentForId:componentId];
|
77
|
|
- UINavigationController* nvc = [self getComponentStack:componentId];
|
78
|
|
- [self assertNavigationControllerExist:nvc reject:rejection];
|
|
41
|
+- (void)popToRoot:(UIViewController*)viewController animated:(BOOL)animated completion:(RNNPopCompletionBlock)completion rejection:(RNNTransitionRejectionBlock)rejection {
|
|
42
|
+ __block NSArray* poppedVCs;
|
79
|
43
|
|
80
|
|
- if ([nvc topViewController] == vc) {
|
81
|
|
- if (vc.options.animations.pop) {
|
82
|
|
- nvc.delegate = vc;
|
83
|
|
- [nvc popViewControllerAnimated:vc.options.animations.pop.enable];
|
84
|
|
- } else {
|
85
|
|
- nvc.delegate = nil;
|
86
|
|
- [nvc popViewControllerAnimated:vc.options.animations.pop.enable];
|
87
|
|
- }
|
88
|
|
- } else {
|
89
|
|
- NSMutableArray * vcs = nvc.viewControllers.mutableCopy;
|
90
|
|
- [vcs removeObject:vc];
|
91
|
|
- [nvc setViewControllers:vcs animated:vc.options.animations.pop.enable];
|
92
|
|
- }
|
93
|
|
- [_store removeComponent:componentId];
|
|
44
|
+ [self performAnimationBlock:^{
|
|
45
|
+ poppedVCs = [viewController.navigationController popToRootViewControllerAnimated:animated];
|
|
46
|
+ } completion:^{
|
|
47
|
+ completion(poppedVCs);
|
|
48
|
+ }];
|
94
|
49
|
}
|
95
|
50
|
|
96
|
|
--(void)popTo:(NSString*)componentId rejection:(RCTPromiseRejectBlock)rejection {
|
97
|
|
- RNNRootViewController *vc = (RNNRootViewController*)[_store findComponentForId:componentId];
|
98
|
|
- RNNNavigationController *nvc = [self getComponentStack:componentId];
|
99
|
|
- [self assertNavigationControllerExist:nvc reject:rejection];
|
|
51
|
+- (void)setStackRoot:(UIViewController *)newRoot fromViewController:(UIViewController *)fromViewController animated:(BOOL)animated completion:(RNNTransitionCompletionBlock)completion rejection:(RNNTransitionRejectionBlock)rejection {
|
|
52
|
+ UINavigationController* nvc = fromViewController.navigationController;
|
100
|
53
|
|
101
|
|
- if (vc && nvc) {
|
102
|
|
- NSArray *poppedVCs = [nvc popToViewController:vc animated:vc.options.animations.pop.enable];
|
103
|
|
- [self removePopedViewControllers:poppedVCs];
|
104
|
|
- }
|
|
54
|
+ [self performAnimationBlock:^{
|
|
55
|
+ [nvc setViewControllers:@[newRoot] animated:animated];
|
|
56
|
+ } completion:completion];
|
105
|
57
|
}
|
106
|
58
|
|
107
|
|
--(void)popToRoot:(NSString*)componentId rejection:(RCTPromiseRejectBlock)rejection {
|
108
|
|
- RNNRootViewController *vc = (RNNRootViewController*)[_store findComponentForId:componentId];
|
109
|
|
- RNNNavigationController *nvc = [self getComponentStack:componentId];
|
110
|
|
- [self assertNavigationControllerExist:nvc reject:rejection];
|
111
|
|
- NSArray* poppedVCs = [nvc popToRootViewControllerAnimated:vc.options.animations.pop.enable];
|
112
|
|
- [self removePopedViewControllers:poppedVCs];
|
113
|
|
-}
|
114
|
|
-
|
115
|
|
--(void)setStackRoot:(UIViewController<RNNRootViewProtocol> *)newRoot fromComponent:(NSString *)componentId completion:(RNNTransitionCompletionBlock)completion rejection:(RCTPromiseRejectBlock)rejection {
|
116
|
|
- RNNNavigationController* nvc = [self getComponentStack:componentId];
|
|
59
|
+# pragma mark Private
|
117
|
60
|
|
118
|
|
- [self assertNavigationControllerExist:nvc reject:rejection];
|
119
|
|
-
|
|
61
|
+- (void)performAnimationBlock:(RNNAnimationBlock)animationBlock completion:(RNNTransitionCompletionBlock)completion {
|
120
|
62
|
[CATransaction begin];
|
121
|
63
|
[CATransaction setCompletionBlock:^{
|
122
|
64
|
if (completion) {
|
|
@@ -124,31 +66,10 @@ dispatch_queue_t RCTGetUIManagerQueue(void);
|
124
|
66
|
}
|
125
|
67
|
}];
|
126
|
68
|
|
127
|
|
- [nvc setViewControllers:@[newRoot] animated:newRoot.options.animations.push.enable];
|
|
69
|
+ animationBlock();
|
128
|
70
|
|
129
|
71
|
[CATransaction commit];
|
130
|
72
|
}
|
131
|
73
|
|
132
|
|
-- (void)assertNavigationControllerExist:(UINavigationController *)viewController reject:(RCTPromiseRejectBlock)reject {
|
133
|
|
- if (![viewController isKindOfClass:[UINavigationController class]]) {
|
134
|
|
- _completionBlock = nil;
|
135
|
|
- [RNNErrorHandler reject:reject withErrorCode:RNNCommandErrorCodeNoStack errorDescription:[NSString stringWithFormat:@"%@ should be called from a stack child component", [RNNErrorHandler getCallerFunctionName]]];
|
136
|
|
- }
|
137
|
|
-}
|
138
|
|
-
|
139
|
|
-- (RNNNavigationController*)getComponentStack:(NSString *)componentId {
|
140
|
|
- UIViewController* component = [_store findComponentForId:componentId];
|
141
|
|
- if ([component isKindOfClass:[UINavigationController class]]) {
|
142
|
|
- return (RNNNavigationController*)component;
|
143
|
|
- } else {
|
144
|
|
- return (RNNNavigationController*)component.navigationController;
|
145
|
|
- }
|
146
|
|
-}
|
147
|
|
-
|
148
|
|
--(void)removePopedViewControllers:(NSArray*)viewControllers {
|
149
|
|
- for (UIViewController *popedVC in viewControllers) {
|
150
|
|
- [_store removeComponentByViewControllerInstance:popedVC];
|
151
|
|
- }
|
152
|
|
-}
|
153
|
74
|
|
154
|
75
|
@end
|