瀏覽代碼

Explicit attaching and detaching viewControllers in store (#4947)

* Explicitly attach and detach viewControllers in store
* Stop registering components in commands handler
Yogev Ben David 5 年之前
父節點
當前提交
28300597ed
共有 40 個檔案被更改,包括 369 行新增564 行删除
  1. 4
    0
      lib/ios/RNNBasePresenter.h
  2. 7
    0
      lib/ios/RNNBasePresenter.m
  3. 11
    21
      lib/ios/RNNCommandsHandler.m
  4. 3
    3
      lib/ios/RNNControllerFactory.h
  5. 27
    23
      lib/ios/RNNControllerFactory.m
  6. 10
    5
      lib/ios/RNNLayoutProtocol.h
  7. 2
    1
      lib/ios/RNNModalManager.m
  8. 1
    0
      lib/ios/RNNNavigationButtons.m
  9. 2
    8
      lib/ios/RNNNavigationController.h
  10. 2
    67
      lib/ios/RNNNavigationController.m
  11. 0
    2
      lib/ios/RNNNavigationControllerPresenter.h
  12. 1
    0
      lib/ios/RNNNavigationControllerPresenter.m
  13. 0
    13
      lib/ios/RNNParentProtocol.h
  14. 2
    3
      lib/ios/RNNRootViewController.h
  15. 5
    26
      lib/ios/RNNRootViewController.m
  16. 2
    6
      lib/ios/RNNSideMenuChildVC.h
  17. 1
    19
      lib/ios/RNNSideMenuChildVC.m
  18. 5
    8
      lib/ios/RNNSideMenuController.h
  19. 1
    45
      lib/ios/RNNSideMenuController.m
  20. 3
    6
      lib/ios/RNNSplitViewController.h
  21. 1
    63
      lib/ios/RNNSplitViewController.m
  22. 0
    1
      lib/ios/RNNSplitViewOptions.m
  23. 1
    2
      lib/ios/RNNStore.h
  24. 0
    7
      lib/ios/RNNStore.m
  25. 2
    10
      lib/ios/RNNTabBarController.h
  26. 5
    77
      lib/ios/RNNTabBarController.m
  27. 2
    7
      lib/ios/RNNTopTabsViewController.h
  28. 5
    44
      lib/ios/RNNTopTabsViewController.m
  29. 1
    0
      lib/ios/RNNViewControllerPresenter.m
  30. 12
    4
      lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj
  31. 7
    59
      lib/ios/ReactNativeNavigationTests/RNNCommandsHandlerTest.m
  32. 7
    3
      lib/ios/ReactNativeNavigationTests/RNNNavigationControllerTest.m
  33. 11
    6
      lib/ios/ReactNativeNavigationTests/RNNRootViewControllerTest.m
  34. 1
    1
      lib/ios/ReactNativeNavigationTests/RNNSideMenuControllerTest.m
  35. 0
    11
      lib/ios/ReactNativeNavigationTests/RNNStoreTest.m
  36. 11
    6
      lib/ios/ReactNativeNavigationTests/RNNTabBarControllerTest.m
  37. 35
    0
      lib/ios/ReactNativeNavigationTests/UIViewController+LayoutProtocolTest.m
  38. 30
    0
      lib/ios/UIViewController+LayoutProtocol.h
  39. 145
    0
      lib/ios/UIViewController+LayoutProtocol.m
  40. 4
    7
      playground/src/screens/OverlayAlert.js

+ 4
- 0
lib/ios/RNNBasePresenter.h 查看文件

@@ -1,5 +1,7 @@
1 1
 #import "RNNNavigationOptions.h"
2 2
 
3
+typedef void (^RNNReactViewReadyCompletionBlock)(void);
4
+
3 5
 @interface RNNBasePresenter : NSObject
4 6
 
5 7
 @property (nonatomic, weak) id bindedViewController;
@@ -16,4 +18,6 @@
16 18
 
17 19
 - (void)mergeOptions:(RNNNavigationOptions *)newOptions currentOptions:(RNNNavigationOptions *)currentOptions defaultOptions:(RNNNavigationOptions *)defaultOptions;
18 20
 
21
+- (void)renderComponents:(RNNNavigationOptions *)options perform:(RNNReactViewReadyCompletionBlock)readyBlock;
22
+
19 23
 @end

+ 7
- 0
lib/ios/RNNBasePresenter.m 查看文件

@@ -2,6 +2,7 @@
2 2
 #import "UIViewController+RNNOptions.h"
3 3
 #import "RNNTabBarItemCreator.h"
4 4
 #import "RNNReactComponentRegistry.h"
5
+#import "UIViewController+LayoutProtocol.h"
5 6
 
6 7
 @interface RNNBasePresenter ()
7 8
 @property (nonatomic, strong) RNNReactComponentRegistry* componentRegistry;
@@ -134,5 +135,11 @@
134 135
 	}
135 136
 }
136 137
 
138
+- (void)renderComponents:(RNNNavigationOptions *)options perform:(RNNReactViewReadyCompletionBlock)readyBlock {
139
+	if (readyBlock) {
140
+		readyBlock();
141
+		readyBlock = nil;
142
+	}
143
+}
137 144
 
138 145
 @end

+ 11
- 21
lib/ios/RNNCommandsHandler.m 查看文件

@@ -8,6 +8,7 @@
8 8
 #import "RNNDefaultOptionsHelper.h"
9 9
 #import "UIViewController+RNNOptions.h"
10 10
 #import "React/RCTI18nUtil.h"
11
+#import "UIViewController+LayoutProtocol.h"
11 12
 
12 13
 static NSString* const setRoot	= @"setRoot";
13 14
 static NSString* const setStackRoot	= @"setStackRoot";
@@ -73,9 +74,8 @@ static NSString* const setDefaultOptions	= @"setDefaultOptions";
73 74
 	}
74 75
 
75 76
 	[_modalManager dismissAllModalsAnimated:NO];
76
-	[_store removeAllComponentsFromWindow:_mainWindow];
77 77
 	
78
-	UIViewController<RNNLayoutProtocol> *vc = [_controllerFactory createLayout:layout[@"root"]];
78
+	UIViewController *vc = [_controllerFactory createLayout:layout[@"root"]];
79 79
 	
80 80
 	[vc renderTreeAndWait:[vc.resolveOptions.animations.setRoot.waitForRender getWithDefaultValue:NO] perform:^{
81 81
 		_mainWindow.rootViewController = vc;
@@ -114,7 +114,7 @@ static NSString* const setDefaultOptions	= @"setDefaultOptions";
114 114
 - (void)push:(NSString*)componentId commandId:(NSString*)commandId layout:(NSDictionary*)layout completion:(RNNTransitionCompletionBlock)completion rejection:(RCTPromiseRejectBlock)rejection {
115 115
 	[self assertReady];
116 116
 	
117
-	UIViewController<RNNLayoutProtocol> *newVc = [_controllerFactory createLayout:layout];
117
+	UIViewController *newVc = [_controllerFactory createLayout:layout];
118 118
 	UIViewController *fromVC = [_store findComponentForId:componentId];
119 119
 	
120 120
 	if ([[newVc.resolveOptions.preview.reactTag getWithDefaultValue:@(0)] floatValue] > 0) {
@@ -172,7 +172,7 @@ static NSString* const setDefaultOptions	= @"setDefaultOptions";
172 172
 - (void)setStackRoot:(NSString*)componentId commandId:(NSString*)commandId children:(NSArray*)children completion:(RNNTransitionCompletionBlock)completion rejection:(RCTPromiseRejectBlock)rejection {
173 173
 	[self assertReady];
174 174
 	
175
- 	NSArray<RNNLayoutProtocol> *childViewControllers = [_controllerFactory createChildrenLayout:children];
175
+ 	NSArray *childViewControllers = [_controllerFactory createChildrenLayout:children];
176 176
 	for (UIViewController<RNNLayoutProtocol>* viewController in childViewControllers) {
177 177
 		[viewController renderTreeAndWait:NO perform:nil];
178 178
 	}
@@ -207,7 +207,6 @@ static NSString* const setDefaultOptions	= @"setDefaultOptions";
207 207
 	}
208 208
 	
209 209
 	[_stackManager pop:vc animated:[vc.resolveOptions.animations.pop.enable getWithDefaultValue:YES] completion:^{
210
-		[_store removeComponent:componentId];
211 210
 		[_eventEmitter sendOnNavigationCommandCompletion:pop commandId:commandId params:@{@"componentId": componentId}];
212 211
 		completion();
213 212
 	} rejection:rejection];
@@ -221,7 +220,6 @@ static NSString* const setDefaultOptions	= @"setDefaultOptions";
221 220
 	
222 221
 	[_stackManager popTo:vc animated:[vc.resolveOptions.animations.pop.enable getWithDefaultValue:YES] completion:^(NSArray *poppedViewControllers) {
223 222
 		[_eventEmitter sendOnNavigationCommandCompletion:popTo commandId:commandId params:@{@"componentId": componentId}];
224
-		[self removePopedViewControllers:poppedViewControllers];
225 223
 		completion();
226 224
 	} rejection:rejection];
227 225
 }
@@ -239,7 +237,7 @@ static NSString* const setDefaultOptions	= @"setDefaultOptions";
239 237
 	}];
240 238
 	
241 239
 	[_stackManager popToRoot:vc animated:[vc.resolveOptions.animations.pop.enable getWithDefaultValue:YES] completion:^(NSArray *poppedViewControllers) {
242
-		[self removePopedViewControllers:poppedViewControllers];
240
+
243 241
 	} rejection:^(NSString *code, NSString *message, NSError *error) {
244 242
 		
245 243
 	}];
@@ -250,7 +248,7 @@ static NSString* const setDefaultOptions	= @"setDefaultOptions";
250 248
 - (void)showModal:(NSDictionary*)layout commandId:(NSString *)commandId completion:(RNNTransitionWithComponentIdCompletionBlock)completion {
251 249
 	[self assertReady];
252 250
 	
253
-	UIViewController<RNNParentProtocol> *newVc = [_controllerFactory createLayout:layout];
251
+	UIViewController *newVc = [_controllerFactory createLayout:layout];
254 252
 	
255 253
 	[newVc renderTreeAndWait:[newVc.resolveOptions.animations.showModal.waitForRender getWithDefaultValue:NO] perform:^{
256 254
 		[_modalManager showModal:newVc animated:[newVc.getCurrentChild.resolveOptions.animations.showModal.enable getWithDefaultValue:YES] hasCustomAnimation:newVc.getCurrentChild.resolveOptions.animations.showModal.hasCustomAnimation completion:^(NSString *componentId) {
@@ -263,7 +261,7 @@ static NSString* const setDefaultOptions	= @"setDefaultOptions";
263 261
 - (void)dismissModal:(NSString*)componentId commandId:(NSString*)commandId mergeOptions:(NSDictionary *)mergeOptions completion:(RNNTransitionCompletionBlock)completion rejection:(RNNTransitionRejectionBlock)reject {
264 262
 	[self assertReady];
265 263
 	
266
-	UIViewController<RNNParentProtocol> *modalToDismiss = (UIViewController<RNNParentProtocol>*)[_store findComponentForId:componentId];
264
+	UIViewController *modalToDismiss = (UIViewController *)[_store findComponentForId:componentId];
267 265
 	
268 266
 	if (!modalToDismiss.isModal) {
269 267
 		[RNNErrorHandler reject:reject withErrorCode:1013 errorDescription:@"component is not a modal"];
@@ -272,9 +270,7 @@ static NSString* const setDefaultOptions	= @"setDefaultOptions";
272 270
 	
273 271
 	RNNNavigationOptions *options = [[RNNNavigationOptions alloc] initWithDict:mergeOptions];
274 272
 	[modalToDismiss.getCurrentChild overrideOptions:options];
275
-	
276
-	[self removePopedViewControllers:modalToDismiss.navigationController.viewControllers];
277
-	
273
+		
278 274
 	[CATransaction begin];
279 275
 	[CATransaction setCompletionBlock:^{
280 276
 		[_eventEmitter sendOnNavigationCommandCompletion:dismissModal commandId:commandId params:@{@"componentId": componentId}];
@@ -302,7 +298,7 @@ static NSString* const setDefaultOptions	= @"setDefaultOptions";
302 298
 - (void)showOverlay:(NSDictionary *)layout commandId:(NSString*)commandId completion:(RNNTransitionCompletionBlock)completion {
303 299
 	[self assertReady];
304 300
 	
305
-	UIViewController<RNNParentProtocol>* overlayVC = [_controllerFactory createLayout:layout];
301
+	UIViewController* overlayVC = [_controllerFactory createLayout:layout];
306 302
 	[overlayVC renderTreeAndWait:NO perform:^{
307 303
 		UIWindow* overlayWindow = [[RNNOverlayWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
308 304
 		overlayWindow.rootViewController = overlayVC;
@@ -326,12 +322,6 @@ static NSString* const setDefaultOptions	= @"setDefaultOptions";
326 322
 
327 323
 #pragma mark - private
328 324
 
329
-- (void)removePopedViewControllers:(NSArray*)viewControllers {
330
-	for (UIViewController *popedVC in viewControllers) {
331
-		[_store removeComponentByViewControllerInstance:popedVC];
332
-	}
333
-}
334
-
335 325
 - (void)assertReady {
336 326
 	if (!_store.isReadyToReceiveCommands) {
337 327
 		[[NSException exceptionWithName:@"BridgeNotLoadedError"
@@ -343,13 +333,13 @@ static NSString* const setDefaultOptions	= @"setDefaultOptions";
343 333
 
344 334
 #pragma mark - RNNModalManagerDelegate
345 335
 
346
-- (void)dismissedModal:(UIViewController<RNNParentProtocol> *)viewController {
336
+- (void)dismissedModal:(UIViewController *)viewController {
347 337
 	[_eventEmitter sendModalsDismissedEvent:viewController.layoutInfo.componentId numberOfModalsDismissed:@(1)];
348 338
 }
349 339
 
350 340
 - (void)dismissedMultipleModals:(NSArray *)viewControllers {
351 341
 	if (viewControllers && viewControllers.count) {
352
-		[_eventEmitter sendModalsDismissedEvent:((UIViewController<RNNParentProtocol> *)viewControllers.lastObject).layoutInfo.componentId numberOfModalsDismissed:@(viewControllers.count)];
342
+		[_eventEmitter sendModalsDismissedEvent:((UIViewController *)viewControllers.lastObject).layoutInfo.componentId numberOfModalsDismissed:@(viewControllers.count)];
353 343
 	}
354 344
 }
355 345
 

+ 3
- 3
lib/ios/RNNControllerFactory.h 查看文件

@@ -4,8 +4,8 @@
4 4
 #import "RNNRootViewCreator.h"
5 5
 #import "RNNStore.h"
6 6
 #import "RNNEventEmitter.h"
7
-#import "RNNParentProtocol.h"
8 7
 #import "RNNReactComponentRegistry.h"
8
+#import "RNNNavigationOptions.h"
9 9
 
10 10
 @interface RNNControllerFactory : NSObject
11 11
 
@@ -15,9 +15,9 @@
15 15
 					  componentRegistry:(RNNReactComponentRegistry *)componentRegistry
16 16
 							 andBridge:(RCTBridge*)bridge;
17 17
 
18
-- (UIViewController<RNNParentProtocol> *)createLayout:(NSDictionary*)layout;
18
+- (UIViewController *)createLayout:(NSDictionary*)layout;
19 19
 
20
-- (NSArray<RNNLayoutProtocol> *)createChildrenLayout:(NSArray*)children;
20
+- (NSArray *)createChildrenLayout:(NSArray*)children;
21 21
 
22 22
 @property (nonatomic, strong) RNNEventEmitter *eventEmitter;
23 23
 

+ 27
- 23
lib/ios/RNNControllerFactory.m 查看文件

@@ -43,8 +43,8 @@
43 43
 	return self;
44 44
 }
45 45
 
46
-- (UIViewController<RNNParentProtocol> *)createLayout:(NSDictionary*)layout {
47
-	UIViewController<RNNParentProtocol>* layoutViewController = [self fromTree:layout];
46
+- (UIViewController *)createLayout:(NSDictionary*)layout {
47
+	UIViewController* layoutViewController = [self fromTree:layout];
48 48
 	return layoutViewController;
49 49
 }
50 50
 
@@ -58,10 +58,10 @@
58 58
 
59 59
 # pragma mark private
60 60
 
61
-- (UIViewController<RNNParentProtocol> *)fromTree:(NSDictionary*)json {
61
+- (UIViewController *)fromTree:(NSDictionary*)json {
62 62
 	RNNLayoutNode* node = [RNNLayoutNode create:json];
63 63
 	
64
-	UIViewController<RNNParentProtocol> *result;
64
+	UIViewController *result;
65 65
 	
66 66
 	if (node.isComponent) {
67 67
 		result = [self createComponent:node];
@@ -106,23 +106,23 @@
106 106
 	if (!result) {
107 107
 		@throw [NSException exceptionWithName:@"UnknownControllerType" reason:[@"Unknown controller type " stringByAppendingString:node.type] userInfo:nil];
108 108
 	}
109
-
110
-	[_store setComponent:result componentId:node.nodeId];
109
+	
110
+	result.store = _store;
111 111
 	
112 112
 	return result;
113 113
 }
114 114
 
115
-- (UIViewController<RNNParentProtocol> *)createComponent:(RNNLayoutNode*)node {
115
+- (UIViewController *)createComponent:(RNNLayoutNode*)node {
116 116
 	RNNLayoutInfo* layoutInfo = [[RNNLayoutInfo alloc] initWithNode:node];
117 117
 	RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:node.data[@"options"]];;
118 118
 	RNNViewControllerPresenter* presenter = [[RNNViewControllerPresenter alloc] initWithComponentRegistry:_componentRegistry];
119 119
 	
120 120
 	RNNRootViewController* component = [[RNNRootViewController alloc] initWithLayoutInfo:layoutInfo rootViewCreator:_creator eventEmitter:_eventEmitter presenter:presenter options:options defaultOptions:_defaultOptions];
121 121
 	
122
-	return (UIViewController<RNNParentProtocol> *)component;
122
+	return (UIViewController *)component;
123 123
 }
124 124
 
125
-- (UIViewController<RNNParentProtocol> *)createExternalComponent:(RNNLayoutNode*)node {
125
+- (UIViewController *)createExternalComponent:(RNNLayoutNode*)node {
126 126
 	RNNLayoutInfo* layoutInfo = [[RNNLayoutInfo alloc] initWithNode:node];
127 127
 	RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:node.data[@"options"]];;
128 128
 	RNNViewControllerPresenter* presenter = [[RNNViewControllerPresenter alloc] init];
@@ -132,61 +132,64 @@
132 132
 	RNNRootViewController* component = [[RNNRootViewController alloc] initExternalComponentWithLayoutInfo:layoutInfo eventEmitter:_eventEmitter presenter:presenter options:options defaultOptions:_defaultOptions];
133 133
 	[component bindViewController:externalVC];
134 134
 	
135
-	return (UIViewController<RNNParentProtocol> *)component;
135
+	return (UIViewController *)component;
136 136
 }
137 137
 
138 138
 
139
-- (UIViewController<RNNParentProtocol> *)createStack:(RNNLayoutNode*)node {
139
+- (UIViewController *)createStack:(RNNLayoutNode*)node {
140 140
 	RNNNavigationControllerPresenter* presenter = [[RNNNavigationControllerPresenter alloc] initWithComponentRegistry:_componentRegistry];
141 141
 	RNNLayoutInfo* layoutInfo = [[RNNLayoutInfo alloc] initWithNode:node];
142 142
 	RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:node.data[@"options"]];;
143 143
 	
144 144
 	NSArray *childViewControllers = [self extractChildrenViewControllersFromNode:node];
145 145
 	
146
-	RNNNavigationController* stack = [[RNNNavigationController alloc] initWithLayoutInfo:layoutInfo creator:_creator childViewControllers:childViewControllers options:options defaultOptions:_defaultOptions presenter:presenter];
146
+	RNNNavigationController* stack = [[RNNNavigationController alloc] initWithLayoutInfo:layoutInfo creator:_creator options:options defaultOptions:_defaultOptions presenter:presenter eventEmitter:_eventEmitter];
147
+	[stack setViewControllers:childViewControllers];
147 148
 	
148 149
 	return stack;
149 150
 }
150 151
 
151
--(UIViewController<RNNParentProtocol> *)createTabs:(RNNLayoutNode*)node {
152
+-(UIViewController *)createTabs:(RNNLayoutNode*)node {
152 153
 	RNNLayoutInfo* layoutInfo = [[RNNLayoutInfo alloc] initWithNode:node];
153 154
 	RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:node.data[@"options"]];;
154 155
 	RNNTabBarPresenter* presenter = [[RNNTabBarPresenter alloc] init];
155 156
 
156 157
 	NSArray *childViewControllers = [self extractChildrenViewControllersFromNode:node];
157 158
 	
158
-	RNNTabBarController* tabsController = [[RNNTabBarController alloc] initWithLayoutInfo:layoutInfo childViewControllers:childViewControllers options:options defaultOptions:_defaultOptions presenter:presenter eventEmitter:_eventEmitter];
159
+	RNNTabBarController* tabsController = [[RNNTabBarController alloc] initWithLayoutInfo:layoutInfo creator:_creator options:options defaultOptions:_defaultOptions presenter:presenter eventEmitter:_eventEmitter];
160
+	[tabsController setViewControllers:childViewControllers];
159 161
 	
160 162
 	return tabsController;
161 163
 }
162 164
 
163
-- (UIViewController<RNNParentProtocol> *)createTopTabs:(RNNLayoutNode*)node {
165
+- (UIViewController *)createTopTabs:(RNNLayoutNode*)node {
164 166
 	RNNLayoutInfo* layoutInfo = [[RNNLayoutInfo alloc] initWithNode:node];
165 167
 	RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:node.data[@"options"]];;
166 168
 	RNNViewControllerPresenter* presenter = [[RNNViewControllerPresenter alloc] init];
167 169
 
168 170
 	NSArray *childViewControllers = [self extractChildrenViewControllersFromNode:node];
169 171
 	
170
-	RNNTopTabsViewController* topTabsController = [[RNNTopTabsViewController alloc] initWithLayoutInfo:layoutInfo childViewControllers:childViewControllers options:options defaultOptions:_defaultOptions presenter:presenter];
172
+	RNNTopTabsViewController* topTabsController = [[RNNTopTabsViewController alloc] initWithLayoutInfo:layoutInfo creator:_creator options:options defaultOptions:_defaultOptions presenter:presenter eventEmitter:_eventEmitter];
173
+	[topTabsController setViewControllers:childViewControllers];
171 174
 	
172 175
 	return topTabsController;
173 176
 }
174 177
 
175
-- (UIViewController<RNNParentProtocol> *)createSideMenu:(RNNLayoutNode*)node {
178
+- (UIViewController *)createSideMenu:(RNNLayoutNode*)node {
176 179
 	RNNLayoutInfo* layoutInfo = [[RNNLayoutInfo alloc] initWithNode:node];
177 180
 	RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:node.data[@"options"]];;
178 181
 	RNNSideMenuPresenter* presenter = [[RNNSideMenuPresenter alloc] init];
179 182
 
180 183
 	NSArray *childViewControllers = [self extractChildrenViewControllersFromNode:node];
181 184
 	
182
-	RNNSideMenuController *sideMenu = [[RNNSideMenuController alloc] initWithLayoutInfo:layoutInfo childViewControllers:childViewControllers options:options defaultOptions:_defaultOptions presenter:presenter];
185
+	RNNSideMenuController *sideMenu = [[RNNSideMenuController alloc] initWithLayoutInfo:layoutInfo creator:_creator childViewControllers:childViewControllers options:options defaultOptions:_defaultOptions presenter:presenter eventEmitter:_eventEmitter];
183 186
 	
184 187
 	return sideMenu;
185 188
 }
186 189
 
187 190
 
188
-- (UIViewController<RNNParentProtocol> *)createSideMenuChild:(RNNLayoutNode*)node type:(RNNSideMenuChildType)type {
189
-	UIViewController<RNNParentProtocol>* childVc = [self fromTree:node.children[0]];
191
+- (UIViewController *)createSideMenuChild:(RNNLayoutNode*)node type:(RNNSideMenuChildType)type {
192
+	UIViewController* childVc = [self fromTree:node.children[0]];
190 193
 	RNNLayoutInfo* layoutInfo = [[RNNLayoutInfo alloc] initWithNode:node];
191 194
 	RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:node.data[@"options"]];;
192 195
 
@@ -195,15 +198,16 @@
195 198
 	return sideMenuChild;
196 199
 }
197 200
 
198
-- (UIViewController<RNNParentProtocol> *)createSplitView:(RNNLayoutNode*)node {
201
+- (UIViewController *)createSplitView:(RNNLayoutNode*)node {
199 202
 	RNNLayoutInfo* layoutInfo = [[RNNLayoutInfo alloc] initWithNode:node];
200 203
 	RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:node.data[@"options"]];;
201 204
 	RNNSplitViewControllerPresenter* presenter = [[RNNSplitViewControllerPresenter alloc] init];
202 205
 
203 206
 	NSArray *childViewControllers = [self extractChildrenViewControllersFromNode:node];
204 207
 
205
-	RNNSplitViewController* splitViewController = [[RNNSplitViewController alloc] initWithLayoutInfo:layoutInfo childViewControllers:childViewControllers options:options defaultOptions:_defaultOptions presenter:presenter];
206
-
208
+	RNNSplitViewController* splitViewController = [[RNNSplitViewController alloc] initWithLayoutInfo:layoutInfo creator:_creator options:options defaultOptions:_defaultOptions presenter:presenter eventEmitter:_eventEmitter];
209
+	[splitViewController bindChildViewControllers:childViewControllers];
210
+	
207 211
 	return splitViewController;
208 212
 }
209 213
 

+ 10
- 5
lib/ios/RNNLayoutProtocol.h 查看文件

@@ -1,6 +1,7 @@
1 1
 #import "RNNLayoutInfo.h"
2
-#import "RNNLeafProtocol.h"
3 2
 #import "RNNBasePresenter.h"
3
+#import "RNNRootViewCreator.h"
4
+#import "RNNEventEmitter.h"
4 5
 
5 6
 typedef void (^RNNReactViewReadyCompletionBlock)(void);
6 7
 
@@ -8,10 +9,12 @@ typedef void (^RNNReactViewReadyCompletionBlock)(void);
8 9
 
9 10
 @required
10 11
 
11
-@property (nonatomic, retain) RNNBasePresenter* presenter;
12
-@property (nonatomic, retain) RNNLayoutInfo* layoutInfo;
13
-@property (nonatomic, strong) RNNNavigationOptions* options;
14
-@property (nonatomic, strong) RNNNavigationOptions* defaultOptions;
12
+- (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo
13
+						   creator:(id<RNNRootViewCreator>)creator
14
+						   options:(RNNNavigationOptions *)options
15
+					defaultOptions:(RNNNavigationOptions *)defaultOptions
16
+						 presenter:(RNNBasePresenter *)presenter
17
+					  eventEmitter:(RNNEventEmitter *)eventEmitter;
15 18
 
16 19
 - (void)renderTreeAndWait:(BOOL)wait perform:(RNNReactViewReadyCompletionBlock)readyBlock;
17 20
 
@@ -25,4 +28,6 @@ typedef void (^RNNReactViewReadyCompletionBlock)(void);
25 28
 
26 29
 - (void)overrideOptions:(RNNNavigationOptions *)options;
27 30
 
31
+- (void)onChildWillAppear;
32
+
28 33
 @end

+ 2
- 1
lib/ios/RNNModalManager.m 查看文件

@@ -1,6 +1,7 @@
1 1
 #import "RNNModalManager.h"
2 2
 #import "RNNRootViewController.h"
3 3
 #import "RNNAnimationsTransitionDelegate.h"
4
+#import "RNNLayoutProtocol.h"
4 5
 
5 6
 @implementation RNNModalManager {
6 7
 	NSMutableArray* _pendingModalIdsToDismiss;
@@ -61,7 +62,7 @@
61 62
 
62 63
 
63 64
 -(void)removePendingNextModalIfOnTop:(RNNTransitionCompletionBlock)completion {
64
-	UIViewController<RNNParentProtocol> *modalToDismiss = [_pendingModalIdsToDismiss lastObject];
65
+	UIViewController<RNNLayoutProtocol> *modalToDismiss = [_pendingModalIdsToDismiss lastObject];
65 66
 	RNNNavigationOptions* options = modalToDismiss.resolveOptions;
66 67
 
67 68
 	if(!modalToDismiss) {

+ 1
- 0
lib/ios/RNNNavigationButtons.m 查看文件

@@ -5,6 +5,7 @@
5 5
 #import "UIImage+tint.h"
6 6
 #import "RNNRootViewController.h"
7 7
 #import "UIImage+insets.h"
8
+#import "UIViewController+LayoutProtocol.h"
8 9
 
9 10
 @interface RNNNavigationButtons()
10 11
 

+ 2
- 8
lib/ios/RNNNavigationController.h 查看文件

@@ -1,17 +1,11 @@
1 1
 #import <UIKit/UIKit.h>
2
-#import "RNNParentProtocol.h"
3 2
 #import "RNNNavigationControllerPresenter.h"
4 3
 #import "UINavigationController+RNNOptions.h"
4
+#import "UIViewController+LayoutProtocol.h"
5 5
 
6
-@interface RNNNavigationController : UINavigationController <RNNParentProtocol>
6
+@interface RNNNavigationController : UINavigationController <RNNLayoutProtocol>
7 7
 
8
-@property (nonatomic, retain) RNNLayoutInfo* layoutInfo;
9 8
 @property (nonatomic, retain) RNNNavigationControllerPresenter* presenter;
10
-@property (nonatomic, strong) RNNNavigationOptions* options;
11
-@property (nonatomic, strong) RNNNavigationOptions* defaultOptions;
12
-
13
-
14
-- (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo creator:(id<RNNRootViewCreator>)creator childViewControllers:(NSArray *)childViewControllers options:(RNNNavigationOptions *)options defaultOptions:(RNNNavigationOptions *)defaultOptions presenter:(RNNBasePresenter *)presenter;
15 9
 
16 10
 - (void)setTopBarBackgroundColor:(UIColor *)backgroundColor;
17 11
 

+ 2
- 67
lib/ios/RNNNavigationController.m 查看文件

@@ -1,4 +1,3 @@
1
-
2 1
 #import "RNNNavigationController.h"
3 2
 #import "RNNRootViewController.h"
4 3
 #import "InteractivePopGestureDelegate.h"
@@ -13,69 +12,9 @@ const NSInteger TOP_BAR_TRANSPARENT_TAG = 78264803;
13 12
 
14 13
 @implementation RNNNavigationController
15 14
 
16
-- (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo creator:(id<RNNRootViewCreator>)creator childViewControllers:(NSArray *)childViewControllers options:(RNNNavigationOptions *)options defaultOptions:(RNNNavigationOptions *)defaultOptions presenter:(RNNNavigationControllerPresenter *)presenter {
17
-	self = [super init];
18
-
19
-	self.presenter = presenter;
20
-	[self.presenter bindViewController:self];
21
-	
22
-	self.defaultOptions = defaultOptions;
23
-	self.options = options;
24
-	
25
-	self.layoutInfo = layoutInfo;
26
-	
27
-	[self setViewControllers:childViewControllers];
28
-	
29
-	return self;
30
-}
31
-
32
-- (void)willMoveToParentViewController:(UIViewController *)parent {
33
-	if (parent) {
34
-		[_presenter applyOptionsOnWillMoveToParentViewController:self.resolveOptions];
35
-	}
36
-}
37 15
 
38
-- (void)onChildWillAppear {
39
-	[_presenter applyOptions:self.resolveOptions];
40
-	[_presenter renderComponents:self.resolveOptions perform:nil];
41
-	[((UIViewController<RNNParentProtocol> *)self.parentViewController) onChildWillAppear];
42
-}
43
-
44
-- (RNNNavigationOptions *)resolveOptions {
45
-	return [(RNNNavigationOptions *)[self.options mergeInOptions:self.getCurrentChild.resolveOptions.copy] withDefault:self.defaultOptions];
46
-}
47
-
48
-- (void)mergeOptions:(RNNNavigationOptions *)options {
49
-	[_presenter mergeOptions:options currentOptions:self.options defaultOptions:self.defaultOptions];
50
-	[((UIViewController<RNNLayoutProtocol> *)self.parentViewController) mergeOptions:options];
51
-}
52
-
53
-- (void)overrideOptions:(RNNNavigationOptions *)options {
54
-	[self.options overrideOptions:options];
55
-}
56
-
57
-- (void)renderTreeAndWait:(BOOL)wait perform:(RNNReactViewReadyCompletionBlock)readyBlock {
58
-	dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
59
-		dispatch_group_t group = dispatch_group_create();
60
-		for (UIViewController<RNNLayoutProtocol>* childViewController in self.childViewControllers) {
61
-			dispatch_group_enter(group);
62
-			dispatch_async(dispatch_get_main_queue(), ^{
63
-				[childViewController renderTreeAndWait:wait perform:^{
64
-					dispatch_group_leave(group);
65
-				}];
66
-			});
67
-		}
68
-		
69
-		dispatch_group_enter(group);
70
-		[self.presenter renderComponents:self.resolveOptions perform:^{
71
-			dispatch_group_leave(group);
72
-		}];
73
-		dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
74
-		
75
-		dispatch_async(dispatch_get_main_queue(), ^{
76
-			readyBlock();
77
-		});
78
-	});
16
+- (UIViewController *)getCurrentChild {
17
+	return self.topViewController;
79 18
 }
80 19
 
81 20
 - (UIInterfaceOrientationMask)supportedInterfaceOrientations {
@@ -106,10 +45,6 @@ const NSInteger TOP_BAR_TRANSPARENT_TAG = 78264803;
106 45
 	return [super popViewControllerAnimated:animated];
107 46
 }
108 47
 
109
-- (UIViewController *)getCurrentChild {
110
-	return ((UIViewController<RNNParentProtocol>*)self.topViewController);
111
-}
112
-
113 48
 - (UIViewController *)childViewControllerForStatusBarStyle {
114 49
 	return self.topViewController;
115 50
 }

+ 0
- 2
lib/ios/RNNNavigationControllerPresenter.h 查看文件

@@ -11,6 +11,4 @@
11 11
 
12 12
 - (void)applyOptionsBeforePopping:(RNNNavigationOptions *)options;
13 13
 
14
-- (void)renderComponents:(RNNNavigationOptions *)options perform:(RNNReactViewReadyCompletionBlock)readyBlock;
15
-
16 14
 @end

+ 1
- 0
lib/ios/RNNNavigationControllerPresenter.m 查看文件

@@ -3,6 +3,7 @@
3 3
 #import "RNNNavigationController.h"
4 4
 #import <React/RCTConvert.h>
5 5
 #import "RNNCustomTitleView.h"
6
+#import "UIViewController+LayoutProtocol.h"
6 7
 
7 8
 @interface RNNNavigationControllerPresenter() {
8 9
 	RNNReactComponentRegistry* _componentRegistry;

+ 0
- 13
lib/ios/RNNParentProtocol.h 查看文件

@@ -1,13 +0,0 @@
1
-#import "RNNLayoutProtocol.h"
2
-#import "RNNLeafProtocol.h"
3
-
4
-@protocol RNNParentProtocol <RNNLayoutProtocol, UINavigationControllerDelegate, UIViewControllerTransitioningDelegate, UISplitViewControllerDelegate>
5
-
6
-
7
-@optional
8
-- (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo childViewControllers:(NSArray *)childViewControllers options:(RNNNavigationOptions *)options defaultOptions:(RNNNavigationOptions *)defaultOptions presenter:(RNNBasePresenter *)presenter;
9
-
10
-@required
11
-- (void)onChildWillAppear;
12
-
13
-@end

+ 2
- 3
lib/ios/RNNRootViewController.h 查看文件

@@ -5,13 +5,12 @@
5 5
 #import "RNNAnimator.h"
6 6
 #import "RNNUIBarButtonItem.h"
7 7
 #import "RNNLayoutInfo.h"
8
-#import "RNNLeafProtocol.h"
9 8
 #import "RNNLayoutProtocol.h"
10 9
 #import "RNNViewControllerPresenter.h"
11 10
 
12 11
 typedef void (^PreviewCallback)(UIViewController *vc);
13 12
 
14
-@interface RNNRootViewController : UIViewController	<RNNLeafProtocol, RNNLayoutProtocol, UIViewControllerPreviewingDelegate, UISearchResultsUpdating, UISearchBarDelegate, UINavigationControllerDelegate, UISplitViewControllerDelegate>
13
+@interface RNNRootViewController : UIViewController	<RNNLayoutProtocol, UIViewControllerPreviewingDelegate, UISearchResultsUpdating, UISearchBarDelegate, UINavigationControllerDelegate, UISplitViewControllerDelegate>
15 14
 
16 15
 @property (nonatomic, strong) RNNEventEmitter *eventEmitter;
17 16
 @property (nonatomic, retain) RNNLayoutInfo* layoutInfo;
@@ -19,7 +18,6 @@ typedef void (^PreviewCallback)(UIViewController *vc);
19 18
 @property (nonatomic, strong) RNNNavigationOptions* options;
20 19
 @property (nonatomic, strong) RNNNavigationOptions* defaultOptions;
21 20
 
22
-@property (nonatomic) id<RNNRootViewCreator> creator;
23 21
 @property (nonatomic, strong) RNNAnimator* animator;
24 22
 @property (nonatomic, strong) UIViewController* previewController;
25 23
 @property (nonatomic, copy) PreviewCallback previewCallback;
@@ -41,5 +39,6 @@ typedef void (^PreviewCallback)(UIViewController *vc);
41 39
 
42 40
 - (void)onButtonPress:(RNNUIBarButtonItem *)barButtonItem;
43 41
 
42
+- (void)bindViewController:(UIViewController *)viewController;
44 43
 
45 44
 @end

+ 5
- 26
lib/ios/RNNRootViewController.m 查看文件

@@ -3,26 +3,15 @@
3 3
 #import "RNNAnimator.h"
4 4
 #import "RNNPushAnimation.h"
5 5
 #import "RNNReactView.h"
6
-#import "RNNParentProtocol.h"
7 6
 #import "RNNAnimationsTransitionDelegate.h"
7
+#import "UIViewController+LayoutProtocol.h"
8 8
 
9 9
 @implementation RNNRootViewController
10 10
 
11 11
 @synthesize previewCallback;
12 12
 
13 13
 - (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo rootViewCreator:(id<RNNRootViewCreator>)creator eventEmitter:(RNNEventEmitter *)eventEmitter presenter:(RNNViewControllerPresenter *)presenter options:(RNNNavigationOptions *)options defaultOptions:(RNNNavigationOptions *)defaultOptions {
14
-	self = [super init];
15
-	
16
-	self.layoutInfo = layoutInfo;
17
-	self.creator = creator;
18
-	
19
-	self.eventEmitter = eventEmitter;
20
-	self.presenter = presenter;
21
-	[self.presenter bindViewController:self];
22
-	self.options = options;
23
-	self.defaultOptions = defaultOptions;
24
-	
25
-	[self.presenter applyOptionsOnInit:self.resolveOptions];
14
+	self = [super initWithLayoutInfo:layoutInfo creator:creator options:options defaultOptions:defaultOptions presenter:presenter eventEmitter:eventEmitter];
26 15
 	
27 16
 	self.animator = [[RNNAnimator alloc] initWithTransitionOptions:self.resolveOptions.customTransition];
28 17
 	
@@ -46,12 +35,6 @@
46 35
 	[viewController didMoveToParentViewController:self];
47 36
 }
48 37
 
49
-- (void)willMoveToParentViewController:(UIViewController *)parent {
50
-	if (parent) {
51
-		[_presenter applyOptionsOnWillMoveToParentViewController:self.resolveOptions];
52
-	}
53
-}
54
-
55 38
 - (void)mergeOptions:(RNNNavigationOptions *)options {
56 39
 	[_presenter mergeOptions:options currentOptions:self.options defaultOptions:self.defaultOptions];
57 40
 	[((UIViewController<RNNLayoutProtocol> *)self.parentViewController) mergeOptions:options];
@@ -67,11 +50,7 @@
67 50
 	[_presenter applyOptions:self.resolveOptions];
68 51
 	[_presenter renderComponents:self.resolveOptions perform:nil];
69 52
 	
70
-	[((UIViewController<RNNParentProtocol> *)self.parentViewController) onChildWillAppear];
71
-}
72
-
73
-- (RNNNavigationOptions *)resolveOptions {
74
-	return [self.options withDefault:self.defaultOptions];
53
+	[((UIViewController *)self.parentViewController) onChildWillAppear];
75 54
 }
76 55
 
77 56
 -(void)viewDidAppear:(BOOL)animated {
@@ -97,7 +76,7 @@
97 76
 	}
98 77
 	
99 78
 	__block RNNReactViewReadyCompletionBlock readyBlockCopy = readyBlock;
100
-	UIView* reactView = [_creator createRootView:self.layoutInfo.name rootViewId:self.layoutInfo.componentId availableSize:[UIScreen mainScreen].bounds.size reactViewReadyBlock:^{
79
+	UIView* reactView = [self.creator createRootView:self.layoutInfo.name rootViewId:self.layoutInfo.componentId availableSize:[UIScreen mainScreen].bounds.size reactViewReadyBlock:^{
101 80
 		[_presenter renderComponents:self.resolveOptions perform:^{
102 81
 			if (readyBlockCopy) {
103 82
 				readyBlockCopy();
@@ -115,7 +94,7 @@
115 94
 }
116 95
 
117 96
 - (UIViewController *)getCurrentChild {
118
-	return self;
97
+	return nil;
119 98
 }
120 99
 
121 100
 -(void)updateSearchResultsForSearchController:(UISearchController *)searchController {

+ 2
- 6
lib/ios/RNNSideMenuChildVC.h 查看文件

@@ -1,6 +1,6 @@
1 1
 #import <UIKit/UIKit.h>
2
-#import "RNNParentProtocol.h"
3 2
 #import "RNNViewControllerPresenter.h"
3
+#import "RNNLayoutProtocol.h"
4 4
 
5 5
 typedef NS_ENUM(NSInteger, RNNSideMenuChildType) {
6 6
 	RNNSideMenuChildTypeCenter,
@@ -9,15 +9,11 @@ typedef NS_ENUM(NSInteger, RNNSideMenuChildType) {
9 9
 };
10 10
 
11 11
 
12
-@interface RNNSideMenuChildVC : UIViewController <RNNParentProtocol>
12
+@interface RNNSideMenuChildVC : UIViewController <RNNLayoutProtocol>
13 13
 
14 14
 @property (readonly) RNNSideMenuChildType type;
15 15
 @property (readonly) UIViewController<RNNLayoutProtocol> *child;
16 16
 
17
-@property (nonatomic, retain) RNNLayoutInfo* layoutInfo;
18
-@property (nonatomic, retain) RNNViewControllerPresenter* presenter;
19
-@property (nonatomic, strong) RNNNavigationOptions* options;
20
-@property (nonatomic, strong) RNNNavigationOptions* defaultOptions;
21 17
 
22 18
 - (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo childViewControllers:(NSArray *)childViewControllers options:(RNNNavigationOptions *)options defaultOptions:(RNNNavigationOptions *)defaultOptions presenter:(RNNViewControllerPresenter *)presenter type:(RNNSideMenuChildType)type;
23 19
 

+ 1
- 19
lib/ios/RNNSideMenuChildVC.m 查看文件

@@ -1,5 +1,5 @@
1 1
 #import "RNNSideMenuChildVC.h"
2
-
2
+#import "UIViewController+LayoutProtocol.h"
3 3
 @interface RNNSideMenuChildVC ()
4 4
 
5 5
 @property (readwrite) RNNSideMenuChildType type;
@@ -34,24 +34,6 @@
34 34
 	return self;
35 35
 }
36 36
 
37
-- (void)onChildWillAppear {
38
-	[_presenter applyOptions:self.resolveOptions];
39
-	[((UIViewController<RNNParentProtocol> *)self.parentViewController) onChildWillAppear];
40
-}
41
-
42
-- (RNNNavigationOptions *)resolveOptions {
43
-	return [(RNNNavigationOptions *)[self.options mergeInOptions:self.getCurrentChild.resolveOptions.copy] withDefault:self.defaultOptions];
44
-}
45
-
46
-- (void)mergeOptions:(RNNNavigationOptions *)options {
47
-	[_presenter mergeOptions:options currentOptions:self.options defaultOptions:self.defaultOptions];
48
-	[((UIViewController<RNNLayoutProtocol> *)self.parentViewController) mergeOptions:options];
49
-}
50
-
51
-- (void)overrideOptions:(RNNNavigationOptions *)options {
52
-	[self.options overrideOptions:options];
53
-}
54
-
55 37
 - (void)renderTreeAndWait:(BOOL)wait perform:(RNNReactViewReadyCompletionBlock)readyBlock {
56 38
 	[self.getCurrentChild renderTreeAndWait:wait perform:readyBlock];
57 39
 }

+ 5
- 8
lib/ios/RNNSideMenuController.h 查看文件

@@ -1,20 +1,17 @@
1 1
 #import <UIKit/UIKit.h>
2 2
 #import "RNNSideMenuChildVC.h"
3 3
 #import "MMDrawerController.h"
4
-#import "RNNParentProtocol.h"
5
-#import "RNNViewControllerPresenter.h"
4
+#import "RNNSideMenuPresenter.h"
5
+#import "UIViewController+LayoutProtocol.h"
6 6
 
7
-@interface RNNSideMenuController : MMDrawerController <RNNParentProtocol>
7
+@interface RNNSideMenuController : MMDrawerController <RNNLayoutProtocol>
8
+
9
+- (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo creator:(id<RNNRootViewCreator>)creator childViewControllers:(NSArray *)childViewControllers options:(RNNNavigationOptions *)options defaultOptions:(RNNNavigationOptions *)defaultOptions presenter:(RNNBasePresenter *)presenter eventEmitter:(RNNEventEmitter *)eventEmitter;
8 10
 
9 11
 @property (readonly) RNNSideMenuChildVC *center;
10 12
 @property (readonly) RNNSideMenuChildVC *left;
11 13
 @property (readonly) RNNSideMenuChildVC *right;
12 14
 
13
-@property (nonatomic, retain) RNNLayoutInfo* layoutInfo;
14
-@property (nonatomic, retain) RNNViewControllerPresenter* presenter;
15
-@property (nonatomic, strong) RNNNavigationOptions* options;
16
-@property (nonatomic, strong) RNNNavigationOptions* defaultOptions;
17
-
18 15
 - (void)side:(MMDrawerSide)side enabled:(BOOL)enabled;
19 16
 - (void)side:(MMDrawerSide)side visible:(BOOL)visible;
20 17
 - (void)side:(MMDrawerSide)side width:(double)width;

+ 1
- 45
lib/ios/RNNSideMenuController.m 查看文件

@@ -13,7 +13,7 @@
13 13
 
14 14
 @implementation RNNSideMenuController
15 15
 
16
-- (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo childViewControllers:(NSArray *)childViewControllers options:(RNNNavigationOptions *)options defaultOptions:(RNNNavigationOptions *)defaultOptions presenter:(RNNViewControllerPresenter *)presenter {
16
+- (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo creator:(id<RNNRootViewCreator>)creator childViewControllers:(NSArray *)childViewControllers options:(RNNNavigationOptions *)options defaultOptions:(RNNNavigationOptions *)defaultOptions presenter:(RNNBasePresenter *)presenter eventEmitter:(RNNEventEmitter *)eventEmitter {
17 17
 	[self setControllers:childViewControllers];
18 18
 	self = [super initWithCenterViewController:self.center leftDrawerViewController:self.left rightDrawerViewController:self.right];
19 19
 	
@@ -36,50 +36,6 @@
36 36
 	return self;
37 37
 }
38 38
 
39
-- (void)willMoveToParentViewController:(UIViewController *)parent {
40
-	if (parent) {
41
-		[_presenter applyOptionsOnWillMoveToParentViewController:self.resolveOptions];
42
-	}
43
-}
44
-
45
-- (void)onChildWillAppear {
46
-	[_presenter applyOptions:self.resolveOptions];
47
-	[((UIViewController<RNNParentProtocol> *)self.parentViewController) onChildWillAppear];
48
-}
49
-
50
-- (RNNNavigationOptions *)resolveOptions {
51
-	return [(RNNNavigationOptions *)[self.options mergeInOptions:self.getCurrentChild.resolveOptions.copy] withDefault:self.defaultOptions];
52
-}
53
-
54
-- (void)mergeOptions:(RNNNavigationOptions *)options {
55
-	[_presenter mergeOptions:options currentOptions:self.options defaultOptions:self.defaultOptions];
56
-	[((UIViewController<RNNLayoutProtocol> *)self.parentViewController) mergeOptions:options];
57
-}
58
-
59
-- (void)overrideOptions:(RNNNavigationOptions *)options {
60
-	[self.options overrideOptions:options];
61
-}
62
-
63
-- (void)renderTreeAndWait:(BOOL)wait perform:(RNNReactViewReadyCompletionBlock)readyBlock {
64
-	dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
65
-		dispatch_group_t group = dispatch_group_create();
66
-		for (UIViewController<RNNLayoutProtocol>* childViewController in self.childViewControllers) {
67
-			dispatch_group_enter(group);
68
-			dispatch_async(dispatch_get_main_queue(), ^{
69
-				[childViewController renderTreeAndWait:wait perform:^{
70
-					dispatch_group_leave(group);
71
-				}];
72
-			});
73
-		}
74
-		
75
-		dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
76
-		
77
-		dispatch_async(dispatch_get_main_queue(), ^{
78
-			readyBlock();
79
-		});
80
-	});
81
-}
82
-
83 39
 - (void)setAnimationType:(NSString *)animationType {
84 40
 	MMDrawerControllerDrawerVisualStateBlock animationTypeStateBlock = nil;
85 41
 	if ([animationType isEqualToString:@"door"]) animationTypeStateBlock = [MMDrawerVisualState swingingDoorVisualStateBlock];

+ 3
- 6
lib/ios/RNNSplitViewController.h 查看文件

@@ -1,13 +1,10 @@
1 1
 #import <UIKit/UIKit.h>
2
-#import "RNNParentProtocol.h"
3 2
 #import "RNNSplitViewControllerPresenter.h"
4 3
 #import "UISplitViewController+RNNOptions.h"
4
+#import "RNNLayoutProtocol.h"
5 5
 
6
-@interface RNNSplitViewController : UISplitViewController <RNNParentProtocol>
6
+@interface RNNSplitViewController : UISplitViewController <RNNLayoutProtocol>
7 7
 
8
-@property (nonatomic, strong) RNNNavigationOptions* options;
9
-@property (nonatomic, strong) RNNNavigationOptions* defaultOptions;
10
-@property (nonatomic, retain) RNNLayoutInfo* layoutInfo;
11
-@property (nonatomic, retain) RNNSplitViewControllerPresenter* presenter;
8
+- (void)bindChildViewControllers:(NSArray<UIViewController<RNNLayoutProtocol> *> *)viewControllers;
12 9
 
13 10
 @end

+ 1
- 63
lib/ios/RNNSplitViewController.m 查看文件

@@ -1,70 +1,8 @@
1 1
 #import "RNNSplitViewController.h"
2
+#import "UIViewController+LayoutProtocol.h"
2 3
 
3 4
 @implementation RNNSplitViewController
4 5
 
5
-- (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo childViewControllers:(NSArray *)childViewControllers options:(RNNNavigationOptions *)options defaultOptions:(RNNNavigationOptions *)defaultOptions presenter:(RNNSplitViewControllerPresenter *)presenter {
6
-	self = [super init];
7
-
8
-	self.defaultOptions = defaultOptions;
9
-	self.options = options;
10
-
11
-	self.presenter = presenter;
12
-	[self.presenter bindViewController:self];
13
-	[self.presenter applyOptionsOnInit:self.options];
14
-
15
-	self.layoutInfo = layoutInfo;
16
-	
17
-	self.navigationController.delegate = self;
18
-	
19
-	[self bindChildViewControllers:childViewControllers];
20
-
21
-	return self;
22
-}
23
-
24
-- (void)willMoveToParentViewController:(UIViewController *)parent {
25
-	if (parent) {
26
-		[_presenter applyOptionsOnWillMoveToParentViewController:self.resolveOptions];
27
-	}
28
-}
29
-
30
-- (void)onChildWillAppear {
31
-	[_presenter applyOptions:self.resolveOptions];
32
-	[((UISplitViewController<RNNParentProtocol> *)self.parentViewController) onChildWillAppear];
33
-}
34
-
35
-- (RNNNavigationOptions *)resolveOptions {
36
-	return [(RNNNavigationOptions *)[self.options mergeInOptions:self.getCurrentChild.resolveOptions.copy] withDefault:self.defaultOptions];
37
-}
38
-
39
-- (void)mergeOptions:(RNNNavigationOptions *)options {
40
-	[_presenter mergeOptions:options currentOptions:self.options defaultOptions:self.defaultOptions];
41
-	[((UISplitViewController<RNNLayoutProtocol> *)self.parentViewController) mergeOptions:options];
42
-}
43
-
44
-- (void)overrideOptions:(RNNNavigationOptions *)options {
45
-	[self.options overrideOptions:options];
46
-}
47
-
48
-- (void)renderTreeAndWait:(BOOL)wait perform:(RNNReactViewReadyCompletionBlock)readyBlock {
49
-	dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
50
-		dispatch_group_t group = dispatch_group_create();
51
-		for (UIViewController<RNNLayoutProtocol>* childViewController in self.childViewControllers) {
52
-			dispatch_group_enter(group);
53
-			dispatch_async(dispatch_get_main_queue(), ^{
54
-				[childViewController renderTreeAndWait:wait perform:^{
55
-					dispatch_group_leave(group);
56
-				}];
57
-			});
58
-		}
59
-		
60
-		dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
61
-		
62
-		dispatch_async(dispatch_get_main_queue(), ^{
63
-			readyBlock();
64
-		});
65
-	});
66
-}
67
-
68 6
 - (void)bindChildViewControllers:(NSArray<UIViewController<RNNLayoutProtocol> *> *)viewControllers {
69 7
 	[self setViewControllers:viewControllers];
70 8
 	UIViewController<UISplitViewControllerDelegate>* masterViewController = viewControllers[0];

+ 0
- 1
lib/ios/RNNSplitViewOptions.m 查看文件

@@ -1,5 +1,4 @@
1 1
 #import "RNNSplitViewOptions.h"
2
-#import "RNNParentProtocol.h"
3 2
 
4 3
 @implementation RNNSplitViewOptions
5 4
 

+ 1
- 2
lib/ios/RNNStore.h 查看文件

@@ -1,8 +1,8 @@
1 1
 
2 2
 #import <Foundation/Foundation.h>
3 3
 #import <UIKit/UIKit.h>
4
-#import "RNNParentProtocol.h"
5 4
 #import "ReactNativeNavigation.h"
5
+#import "RNNLayoutInfo.h"
6 6
 
7 7
 typedef void (^RNNTransitionCompletionBlock)(void);
8 8
 typedef void (^RNNTransitionWithComponentIdCompletionBlock)(NSString *componentId);
@@ -13,7 +13,6 @@ typedef void (^RNNTransitionRejectionBlock)(NSString *code, NSString *message, N
13 13
 - (UIViewController*)findComponentForId:(NSString*)componentId;
14 14
 - (void)setComponent:(UIViewController*)viewController componentId:(NSString*)componentId;
15 15
 - (void)removeComponent:(NSString*)componentId;
16
-- (void)removeComponentByViewControllerInstance:(UIViewController*)componentInstance;
17 16
 - (void)removeAllComponents;
18 17
 - (void)removeAllComponentsFromWindow:(UIWindow *)window;
19 18
 - (void)registerExternalComponent:(NSString *)name callback:(RNNExternalViewCreator)callback;

+ 0
- 7
lib/ios/RNNStore.m 查看文件

@@ -35,13 +35,6 @@
35 35
 	[_componentStore removeObjectForKey:componentId];
36 36
 }
37 37
 
38
-- (void)removeComponentByViewControllerInstance:(UIViewController*)componentInstance {
39
-	NSString *foundKey = [self componentKeyForInstance:componentInstance];
40
-	if (foundKey) {
41
-		[self removeComponent:foundKey];
42
-	}
43
-}
44
-
45 38
 - (void)removeAllComponents {
46 39
 	[_componentStore removeAllObjects];
47 40
 }

+ 2
- 10
lib/ios/RNNTabBarController.h 查看文件

@@ -1,18 +1,10 @@
1 1
 #import <UIKit/UIKit.h>
2
-#import "RNNParentProtocol.h"
3 2
 #import "RNNEventEmitter.h"
4 3
 #import "RNNTabBarPresenter.h"
4
+#import "UIViewController+LayoutProtocol.h"
5 5
 
6
-@interface RNNTabBarController : UITabBarController <RNNParentProtocol, UITabBarControllerDelegate>
7
-
8
-- (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo childViewControllers:(NSArray *)childViewControllers options:(RNNNavigationOptions *)options defaultOptions:(RNNNavigationOptions *)defaultOptions presenter:(RNNTabBarPresenter *)presenter eventEmitter:(RNNEventEmitter *)eventEmitter;
6
+@interface RNNTabBarController : UITabBarController <RNNLayoutProtocol, UITabBarControllerDelegate>
9 7
 
10 8
 - (void)setSelectedIndexByComponentID:(NSString *)componentID;
11 9
 
12
-@property (nonatomic, retain) RNNLayoutInfo* layoutInfo;
13
-@property (nonatomic, retain) RNNTabBarPresenter* presenter;
14
-@property (nonatomic, strong) RNNNavigationOptions* options;
15
-@property (nonatomic, strong) RNNNavigationOptions* defaultOptions;
16
-@property (nonatomic, strong) RNNEventEmitter *eventEmitter;
17
-
18 10
 @end

+ 5
- 77
lib/ios/RNNTabBarController.m 查看文件

@@ -4,80 +4,12 @@
4 4
 	NSUInteger _currentTabIndex;
5 5
 }
6 6
 
7
-- (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo
8
-			  childViewControllers:(NSArray *)childViewControllers
9
-						   options:(RNNNavigationOptions *)options
10
-					defaultOptions:(RNNNavigationOptions *)defaultOptions
11
-						 presenter:(RNNTabBarPresenter *)presenter
12
-					  eventEmitter:(RNNEventEmitter *)eventEmitter {
13
-	self = [self initWithLayoutInfo:layoutInfo childViewControllers:childViewControllers options:options defaultOptions:defaultOptions presenter:presenter];
14
-	
15
-	_eventEmitter = eventEmitter;
16
-	
7
+- (id<UITabBarControllerDelegate>)delegate {
17 8
 	return self;
18 9
 }
19 10
 
20
-- (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo
21
-			  childViewControllers:(NSArray *)childViewControllers
22
-						   options:(RNNNavigationOptions *)options
23
-					defaultOptions:(RNNNavigationOptions *)defaultOptions
24
-						 presenter:(RNNTabBarPresenter *)presenter {
25
-	self = [super init];
26
-	
27
-	self.delegate = self;
28
-	self.options = options;
29
-	self.defaultOptions = defaultOptions;
30
-	self.layoutInfo = layoutInfo;
31
-	self.presenter = presenter;
32
-	[self.presenter bindViewController:self];
33
-	[self setViewControllers:childViewControllers];
34
-	[self.presenter applyOptionsOnInit:self.options];
35
-	
36
-	return self;
37
-}
38
-
39
-- (void)willMoveToParentViewController:(UIViewController *)parent {
40
-	if (parent) {
41
-		[_presenter applyOptionsOnWillMoveToParentViewController:self.resolveOptions];
42
-	}
43
-}
44
-
45
-- (void)onChildWillAppear {
46
-	[_presenter applyOptions:self.resolveOptions];
47
-	[((UIViewController<RNNParentProtocol> *)self.parentViewController) onChildWillAppear];
48
-}
49
-
50
-- (RNNNavigationOptions *)resolveOptions {
51
-	return [(RNNNavigationOptions *)[self.options mergeInOptions:self.getCurrentChild.resolveOptions.copy] withDefault:self.defaultOptions];
52
-}
53
-
54
-- (void)mergeOptions:(RNNNavigationOptions *)options {
55
-	[_presenter mergeOptions:options currentOptions:self.options defaultOptions:self.defaultOptions];
56
-	[((UIViewController<RNNLayoutProtocol> *)self.parentViewController) mergeOptions:options];
57
-}
58
-
59
-- (void)overrideOptions:(RNNNavigationOptions *)options {
60
-	[self.options overrideOptions:options];
61
-}
62
-
63
-- (void)renderTreeAndWait:(BOOL)wait perform:(RNNReactViewReadyCompletionBlock)readyBlock {
64
-	dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
65
-		dispatch_group_t group = dispatch_group_create();
66
-		for (UIViewController<RNNLayoutProtocol>* childViewController in self.childViewControllers) {
67
-			dispatch_group_enter(group);
68
-			dispatch_async(dispatch_get_main_queue(), ^{
69
-				[childViewController renderTreeAndWait:wait perform:^{
70
-					dispatch_group_leave(group);
71
-				}];
72
-			});
73
-		}
74
-		
75
-		dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
76
-		
77
-		dispatch_async(dispatch_get_main_queue(), ^{
78
-			readyBlock();
79
-		});
80
-	});
11
+- (UIViewController *)getCurrentChild {
12
+	return self.selectedViewController;
81 13
 }
82 14
 
83 15
 - (UIInterfaceOrientationMask)supportedInterfaceOrientations {
@@ -99,18 +31,14 @@
99 31
 	[super setSelectedIndex:selectedIndex];
100 32
 }
101 33
 
102
-- (UIViewController *)getCurrentChild {
103
-	return self.selectedViewController;
104
-}
105
-
106 34
 - (UIStatusBarStyle)preferredStatusBarStyle {
107
-	return ((UIViewController<RNNParentProtocol>*)self.selectedViewController).preferredStatusBarStyle;
35
+	return self.selectedViewController.preferredStatusBarStyle;
108 36
 }
109 37
 
110 38
 #pragma mark UITabBarControllerDelegate
111 39
 
112 40
 - (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
113
-	[_eventEmitter sendBottomTabSelected:@(tabBarController.selectedIndex) unselected:@(_currentTabIndex)];
41
+	[self.eventEmitter sendBottomTabSelected:@(tabBarController.selectedIndex) unselected:@(_currentTabIndex)];
114 42
 	_currentTabIndex = tabBarController.selectedIndex;
115 43
 }
116 44
 

+ 2
- 7
lib/ios/RNNTopTabsViewController.h 查看文件

@@ -1,15 +1,10 @@
1 1
 #import <React/RCTUIManager.h>
2
-#import "RNNParentProtocol.h"
2
+#import "RNNLayoutProtocol.h"
3 3
 
4
-@interface RNNTopTabsViewController : UIViewController <RNNParentProtocol>
4
+@interface RNNTopTabsViewController : UIViewController <RNNLayoutProtocol>
5 5
 
6 6
 @property (nonatomic, retain) UIView* contentView;
7 7
 
8
-@property (nonatomic, retain) RNNLayoutInfo* layoutInfo;
9
-@property (nonatomic, retain) RNNBasePresenter* presenter;
10
-@property (nonatomic, strong) RNNNavigationOptions* options;
11
-@property (nonatomic, strong) RNNNavigationOptions* defaultOptions;
12
-
13 8
 - (void)setViewControllers:(NSArray*)viewControllers;
14 9
 - (void)viewController:(UIViewController*)vc changedTitle:(NSString*)title;
15 10
 - (instancetype)init;

+ 5
- 44
lib/ios/RNNTopTabsViewController.m 查看文件

@@ -2,10 +2,11 @@
2 2
 #import "RNNSegmentedControl.h"
3 3
 #import "ReactNativeNavigation.h"
4 4
 #import "RNNRootViewController.h"
5
+#import "UIViewController+LayoutProtocol.h"
5 6
 
6 7
 @interface RNNTopTabsViewController () {
7 8
 	NSArray* _viewControllers;
8
-	UIViewController<RNNParentProtocol>* _currentViewController;
9
+	UIViewController* _currentViewController;
9 10
 	RNNSegmentedControl* _segmentedControl;
10 11
 }
11 12
 
@@ -40,42 +41,8 @@
40 41
 	return self;
41 42
 }
42 43
 
43
-- (void)onChildWillAppear {
44
-	[_presenter applyOptions:self.resolveOptions];
45
-	[((UIViewController<RNNParentProtocol> *)self.parentViewController) onChildWillAppear];
46
-}
47
-
48
-- (RNNNavigationOptions *)resolveOptions {
49
-	return [(RNNNavigationOptions *)[self.options mergeInOptions:self.getCurrentChild.resolveOptions.copy] withDefault:self.defaultOptions];
50
-}
51
-
52
-- (void)mergeOptions:(RNNNavigationOptions *)options {
53
-	[_presenter mergeOptions:options currentOptions:self.options defaultOptions:self.defaultOptions];
54
-	[((UIViewController<RNNLayoutProtocol> *)self.parentViewController) mergeOptions:options];
55
-}
56
-
57
-- (void)overrideOptions:(RNNNavigationOptions *)options {
58
-	[self.options overrideOptions:options];
59
-}
60
-
61
-- (void)renderTreeAndWait:(BOOL)wait perform:(RNNReactViewReadyCompletionBlock)readyBlock {
62
-	dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
63
-		dispatch_group_t group = dispatch_group_create();
64
-		for (UIViewController<RNNLayoutProtocol>* childViewController in self.childViewControllers) {
65
-			dispatch_group_enter(group);
66
-			dispatch_async(dispatch_get_main_queue(), ^{
67
-				[childViewController renderTreeAndWait:wait perform:^{
68
-					dispatch_group_leave(group);
69
-				}];
70
-			});
71
-		}
72
-		
73
-		dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
74
-		
75
-		dispatch_async(dispatch_get_main_queue(), ^{
76
-			readyBlock();
77
-		});
78
-	});
44
+- (UIViewController *)getCurrentChild {
45
+	return _currentViewController;
79 46
 }
80 47
 
81 48
 - (void)createTabBar {
@@ -100,7 +67,7 @@
100 67
 }
101 68
 
102 69
 - (void)setSelectedViewControllerIndex:(NSUInteger)index {
103
-	UIViewController<RNNParentProtocol> *toVC = _viewControllers[index];
70
+	UIViewController *toVC = _viewControllers[index];
104 71
 	[_contentView addSubview:toVC.view];
105 72
 	[_currentViewController.view removeFromSuperview];
106 73
 	_currentViewController = toVC;
@@ -126,10 +93,4 @@
126 93
     [super viewDidLoad];
127 94
 }
128 95
 
129
-#pragma mark RNNParentProtocol
130
-
131
-- (UIViewController *)getCurrentChild {
132
-	return _currentViewController;
133
-}
134
-
135 96
 @end

+ 1
- 0
lib/ios/RNNViewControllerPresenter.m 查看文件

@@ -5,6 +5,7 @@
5 5
 #import "RNNReactView.h"
6 6
 #import "RNNCustomTitleView.h"
7 7
 #import "RNNTitleViewHelper.h"
8
+#import "UIViewController+LayoutProtocol.h"
8 9
 
9 10
 @interface RNNViewControllerPresenter() {
10 11
 	RNNReactView* _customTitleView;

+ 12
- 4
lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj 查看文件

@@ -205,7 +205,6 @@
205 205
 		507F43F51FF4FCFE00D9425B /* HMSegmentedControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 507F43F31FF4FCFE00D9425B /* HMSegmentedControl.m */; };
206 206
 		507F43F81FF525B500D9425B /* RNNSegmentedControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 507F43F61FF525B500D9425B /* RNNSegmentedControl.h */; };
207 207
 		507F43F91FF525B500D9425B /* RNNSegmentedControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 507F43F71FF525B500D9425B /* RNNSegmentedControl.m */; };
208
-		507F44201FFA8A8800D9425B /* RNNParentProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 507F441F1FFA8A8800D9425B /* RNNParentProtocol.h */; };
209 208
 		5085DD2D21DCF75A0032E64B /* RNNSideMenuControllerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 5085DD2C21DCF75A0032E64B /* RNNSideMenuControllerTest.m */; };
210 209
 		50887C1520ECC5C200D06111 /* RNNButtonOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 50887C1320ECC5C200D06111 /* RNNButtonOptions.h */; };
211 210
 		50887C1620ECC5C200D06111 /* RNNButtonOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 50887C1420ECC5C200D06111 /* RNNButtonOptions.m */; };
@@ -215,6 +214,9 @@
215 214
 		509B258F2178BE7A00C83C23 /* RNNNavigationControllerPresenterTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 509B258E2178BE7A00C83C23 /* RNNNavigationControllerPresenterTest.m */; };
216 215
 		50A00C37200F84D6000F01A6 /* RNNOverlayOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 50A00C35200F84D6000F01A6 /* RNNOverlayOptions.h */; };
217 216
 		50A00C38200F84D6000F01A6 /* RNNOverlayOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 50A00C36200F84D6000F01A6 /* RNNOverlayOptions.m */; };
217
+		50AB0B1C2255F8640039DAED /* UIViewController+LayoutProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 50AB0B1A2255F8640039DAED /* UIViewController+LayoutProtocol.h */; };
218
+		50AB0B1D2255F8640039DAED /* UIViewController+LayoutProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = 50AB0B1B2255F8640039DAED /* UIViewController+LayoutProtocol.m */; };
219
+		50AB0B1F22562FA10039DAED /* UIViewController+LayoutProtocolTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 50AB0B1E22562FA10039DAED /* UIViewController+LayoutProtocolTest.m */; };
218 220
 		50BE951220B5A787004F5DF5 /* RNNStatusBarOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 50BE951020B5A787004F5DF5 /* RNNStatusBarOptions.m */; };
219 221
 		50BE951320B5A787004F5DF5 /* RNNStatusBarOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 50BE951120B5A787004F5DF5 /* RNNStatusBarOptions.h */; };
220 222
 		50C4A496206BDDBB00DB292E /* RNNSubtitleOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 50C4A494206BDDBB00DB292E /* RNNSubtitleOptions.h */; };
@@ -542,7 +544,6 @@
542 544
 		507F43F31FF4FCFE00D9425B /* HMSegmentedControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HMSegmentedControl.m; sourceTree = "<group>"; };
543 545
 		507F43F61FF525B500D9425B /* RNNSegmentedControl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNSegmentedControl.h; sourceTree = "<group>"; };
544 546
 		507F43F71FF525B500D9425B /* RNNSegmentedControl.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNSegmentedControl.m; sourceTree = "<group>"; };
545
-		507F441F1FFA8A8800D9425B /* RNNParentProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNNParentProtocol.h; sourceTree = "<group>"; };
546 547
 		5085DD2C21DCF75A0032E64B /* RNNSideMenuControllerTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNSideMenuControllerTest.m; sourceTree = "<group>"; };
547 548
 		50887C1320ECC5C200D06111 /* RNNButtonOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNButtonOptions.h; sourceTree = "<group>"; };
548 549
 		50887C1420ECC5C200D06111 /* RNNButtonOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNButtonOptions.m; sourceTree = "<group>"; };
@@ -552,6 +553,9 @@
552 553
 		509B258E2178BE7A00C83C23 /* RNNNavigationControllerPresenterTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNNavigationControllerPresenterTest.m; sourceTree = "<group>"; };
553 554
 		50A00C35200F84D6000F01A6 /* RNNOverlayOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNOverlayOptions.h; sourceTree = "<group>"; };
554 555
 		50A00C36200F84D6000F01A6 /* RNNOverlayOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNOverlayOptions.m; sourceTree = "<group>"; };
556
+		50AB0B1A2255F8640039DAED /* UIViewController+LayoutProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UIViewController+LayoutProtocol.h"; sourceTree = "<group>"; };
557
+		50AB0B1B2255F8640039DAED /* UIViewController+LayoutProtocol.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIViewController+LayoutProtocol.m"; sourceTree = "<group>"; };
558
+		50AB0B1E22562FA10039DAED /* UIViewController+LayoutProtocolTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIViewController+LayoutProtocolTest.m"; sourceTree = "<group>"; };
555 559
 		50BE951020B5A787004F5DF5 /* RNNStatusBarOptions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNNStatusBarOptions.m; sourceTree = "<group>"; };
556 560
 		50BE951120B5A787004F5DF5 /* RNNStatusBarOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNNStatusBarOptions.h; sourceTree = "<group>"; };
557 561
 		50C4A494206BDDBB00DB292E /* RNNSubtitleOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNSubtitleOptions.h; sourceTree = "<group>"; };
@@ -824,9 +828,10 @@
824 828
 		5012242D2173E0E0000F5F98 /* Protocols */ = {
825 829
 			isa = PBXGroup;
826 830
 			children = (
827
-				507F441F1FFA8A8800D9425B /* RNNParentProtocol.h */,
828 831
 				505EDD33214E7A6A0071C7DE /* RNNLeafProtocol.h */,
829 832
 				505EDD47214FC4A60071C7DE /* RNNLayoutProtocol.h */,
833
+				50AB0B1A2255F8640039DAED /* UIViewController+LayoutProtocol.h */,
834
+				50AB0B1B2255F8640039DAED /* UIViewController+LayoutProtocol.m */,
830 835
 			);
831 836
 			name = Protocols;
832 837
 			sourceTree = "<group>";
@@ -1076,6 +1081,7 @@
1076 1081
 				502F0E132178CF8200367CC3 /* UIViewController+RNNOptionsTest.m */,
1077 1082
 				5038A376216CF252009280BC /* UITabBarController+RNNOptionsTest.m */,
1078 1083
 				509B247F217873FF00C83C23 /* UINavigationController+RNNOptionsTest.m */,
1084
+				50AB0B1E22562FA10039DAED /* UIViewController+LayoutProtocolTest.m */,
1079 1085
 			);
1080 1086
 			path = ReactNativeNavigationTests;
1081 1087
 			sourceTree = "<group>";
@@ -1279,6 +1285,7 @@
1279 1285
 				E8DA24401F97459B00CD552B /* RNNElementFinder.h in Headers */,
1280 1286
 				263905BE1E4C6F440023D7D3 /* RCCTheSideBarManagerViewController.h in Headers */,
1281 1287
 				263905CE1E4C6F440023D7D3 /* TheSidebarController.h in Headers */,
1288
+				50AB0B1C2255F8640039DAED /* UIViewController+LayoutProtocol.h in Headers */,
1282 1289
 				50D031342005149000386B3D /* RNNOverlayManager.h in Headers */,
1283 1290
 				50E5F7952240EBD6002AFEAD /* RNNAnimationsTransitionDelegate.h in Headers */,
1284 1291
 				7B1126A71E2D2B6C00F9B03B /* RNNEventEmitter.h in Headers */,
@@ -1295,7 +1302,6 @@
1295 1302
 				50E5F791223FA04C002AFEAD /* RNNAnimationConfigurationOptions.h in Headers */,
1296 1303
 				5049594E216F6277006D2B81 /* NumberParser.h in Headers */,
1297 1304
 				50BE951320B5A787004F5DF5 /* RNNStatusBarOptions.h in Headers */,
1298
-				507F44201FFA8A8800D9425B /* RNNParentProtocol.h in Headers */,
1299 1305
 				50570BEA2063E09B006A1B5C /* RNNTitleViewHelper.h in Headers */,
1300 1306
 				263905CA1E4C6F440023D7D3 /* SidebarLuvocracyAnimation.h in Headers */,
1301 1307
 				50495956216F6B3D006D2B81 /* DictionaryParser.h in Headers */,
@@ -1446,6 +1452,7 @@
1446 1452
 				5038A379216D01F6009280BC /* RNNBottomTabOptionsTest.m in Sources */,
1447 1453
 				E83BAD681F2734B500A9F3DD /* RNNNavigationOptionsTest.m in Sources */,
1448 1454
 				505EDD32214E4BE80071C7DE /* RNNNavigationControllerTest.m in Sources */,
1455
+				50AB0B1F22562FA10039DAED /* UIViewController+LayoutProtocolTest.m in Sources */,
1449 1456
 				7B49FECF1E95098500DEB3EA /* RNNNavigationStackManagerTest.m in Sources */,
1450 1457
 				509B2480217873FF00C83C23 /* UINavigationController+RNNOptionsTest.m in Sources */,
1451 1458
 				506F630D216A599300AD0D0A /* RNNTabBarControllerTest.m in Sources */,
@@ -1467,6 +1474,7 @@
1467 1474
 			files = (
1468 1475
 				263905C71E4C6F440023D7D3 /* SidebarFeedlyAnimation.m in Sources */,
1469 1476
 				50C4A497206BDDBB00DB292E /* RNNSubtitleOptions.m in Sources */,
1477
+				50AB0B1D2255F8640039DAED /* UIViewController+LayoutProtocol.m in Sources */,
1470 1478
 				263905B41E4C6F440023D7D3 /* MMDrawerVisualState.m in Sources */,
1471 1479
 				5012240B21735959000F5F98 /* RNNSideMenuPresenter.m in Sources */,
1472 1480
 				502CB46F20CD1DDA0019B2FE /* RNNBackButtonOptions.m in Sources */,

+ 7
- 59
lib/ios/ReactNativeNavigationTests/RNNCommandsHandlerTest.m 查看文件

@@ -122,21 +122,22 @@
122 122
 	initialOptions.topBar.title.text = [[Text alloc] initWithValue:@"the title"];
123 123
 	RNNLayoutInfo* layoutInfo = [RNNLayoutInfo new];
124 124
 	RNNTestRootViewCreator* creator = [[RNNTestRootViewCreator alloc] init];
125
-	
125
+
126 126
 	RNNViewControllerPresenter* presenter = [[RNNViewControllerPresenter alloc] init];
127 127
 	RNNRootViewController* vc = [[RNNRootViewController alloc] initWithLayoutInfo:layoutInfo rootViewCreator:creator eventEmitter:nil presenter:presenter options:initialOptions defaultOptions:nil];
128
-	
129
-	RNNNavigationController* nav = [[RNNNavigationController alloc] initWithLayoutInfo:nil creator:creator childViewControllers:@[vc] options:[[RNNNavigationOptions alloc] initEmptyOptions] defaultOptions:nil presenter:[[RNNNavigationControllerPresenter alloc] init]];
128
+
129
+	RNNNavigationController* nav = [[RNNNavigationController alloc] initWithLayoutInfo:nil creator:creator options:[[RNNNavigationOptions alloc] initEmptyOptions] defaultOptions:nil presenter:[[RNNNavigationControllerPresenter alloc] init] eventEmitter:nil];
130
+	[nav setViewControllers:@[vc]];
130 131
 	
131 132
 	[vc viewWillAppear:false];
132 133
 	XCTAssertTrue([vc.navigationItem.title isEqual:@"the title"]);
133
-	
134
+
134 135
 	[self.store setReadyToReceiveCommands:true];
135 136
 	[self.store setComponent:vc componentId:@"componentId"];
136
-	
137
+
137 138
 	NSDictionary* dictFromJs = @{@"topBar": @{@"background" : @{@"color" : @(0xFFFF0000)}}};
138 139
 	UIColor* expectedColor = [UIColor colorWithRed:1 green:0 blue:0 alpha:1];
139
-	
140
+
140 141
 	[self.uut mergeOptions:@"componentId" options:dictFromJs completion:^{
141 142
 		XCTAssertTrue([vc.navigationItem.title isEqual:@"the title"]);
142 143
 		XCTAssertTrue([nav.navigationBar.barTintColor isEqual:expectedColor]);
@@ -164,50 +165,6 @@
164 165
 	}];
165 166
 }
166 167
 
167
-- (void)testPop_removeTopVCFromStore {
168
-	[self.store setReadyToReceiveCommands:true];
169
-	XCTestExpectation *expectation = [self expectationWithDescription:@"Testing Async Method"];
170
-	
171
-	[self.uut pop:@"vc3" commandId:@"" mergeOptions:nil completion:^{
172
-		XCTAssertNil([self.store findComponentForId:@"vc3"]);
173
-		XCTAssertNotNil([self.store findComponentForId:@"vc2"]);
174
-		XCTAssertNotNil([self.store findComponentForId:@"vc1"]);
175
-		[expectation fulfill];
176
-	} rejection:^(NSString *code, NSString *message, NSError *error) {
177
-		
178
-	}];
179
-	
180
-	[self waitForExpectationsWithTimeout:1 handler:nil];
181
-}
182
-
183
-- (void)testPopToSpecificVC_removeAllPopedVCFromStore {
184
-	[self.store setReadyToReceiveCommands:true];
185
-	XCTestExpectation *expectation = [self expectationWithDescription:@"Testing Async Method"];
186
-	_nvc.willReturnVCs = @[self.vc2, self.vc3];
187
-	[self.uut popTo:@"vc1" commandId:@"" mergeOptions:nil completion:^{
188
-		XCTAssertNil([self.store findComponentForId:@"vc2"]);
189
-		XCTAssertNil([self.store findComponentForId:@"vc3"]);
190
-		XCTAssertNotNil([self.store findComponentForId:@"vc1"]);
191
-		[expectation fulfill];
192
-	} rejection:nil];
193
-	
194
-	[self waitForExpectationsWithTimeout:1 handler:nil];
195
-}
196
-
197
-- (void)testPopToRoot_removeAllTopVCsFromStore {
198
-	[self.store setReadyToReceiveCommands:true];
199
-	_nvc.willReturnVCs = @[self.vc2, self.vc3];
200
-	XCTestExpectation *expectation = [self expectationWithDescription:@"Testing Async Method"];
201
-	[self.uut popToRoot:@"vc3" commandId:@"" mergeOptions:nil completion:^{
202
-		XCTAssertNil([self.store findComponentForId:@"vc2"]);
203
-		XCTAssertNil([self.store findComponentForId:@"vc3"]);
204
-		XCTAssertNotNil([self.store findComponentForId:@"vc1"]);
205
-		[expectation fulfill];
206
-	} rejection:nil];
207
-	
208
-	[self waitForExpectationsWithTimeout:1 handler:nil];
209
-}
210
-
211 168
 - (void)testShowOverlay_createLayout {
212 169
 	[self.store setReadyToReceiveCommands:true];
213 170
 	OCMStub([self.overlayManager showOverlayWindow:[OCMArg any]]);
@@ -302,15 +259,6 @@
302 259
 	[self.mainWindow verify];
303 260
 }
304 261
 
305
-- (void)testSetRoot_removeAllComponentsFromMainWindow {
306
-	[self.store setReadyToReceiveCommands:true];
307
-	OCMStub([self.controllerFactory createLayout:[OCMArg any]]).andReturn(self.vc1);
308
-	
309
-	[[self.store expect] removeAllComponentsFromWindow:self.mainWindow];
310
-	[self.uut setRoot:@{} commandId:@"" completion:^{}];
311
-	[self.store verify];
312
-}
313
-
314 262
 - (void)testSetStackRoot_resetStackWithSingleComponent {
315 263
 	OCMStub([self.controllerFactory createChildrenLayout:[OCMArg any]]).andReturn(@[self.vc2]);
316 264
 	[self.store setReadyToReceiveCommands:true];

+ 7
- 3
lib/ios/ReactNativeNavigationTests/RNNNavigationControllerTest.m 查看文件

@@ -27,7 +27,8 @@
27 27
 	_vc2Mock = [OCMockObject partialMockForObject:_vc2];
28 28
 	_vc3 = [UIViewController new];
29 29
 	_options = [OCMockObject partialMockForObject:[[RNNNavigationOptions alloc] initEmptyOptions]];
30
-	self.uut = [[RNNNavigationController alloc] initWithLayoutInfo:nil creator:_creator childViewControllers:@[_vc1, _vc2] options:_options defaultOptions:nil presenter:[OCMockObject partialMockForObject:[[RNNNavigationControllerPresenter alloc] init]]];
30
+	self.uut = [[RNNNavigationController alloc] initWithLayoutInfo:nil creator:_creator options:_options defaultOptions:nil presenter:[OCMockObject partialMockForObject:[[RNNNavigationControllerPresenter alloc] init]] eventEmitter:nil];
31
+	[self.uut setViewControllers:@[_vc1, _vc2]];
31 32
 }
32 33
 
33 34
 - (void)testInitWithLayoutInfo_shouldBindPresenter {
@@ -35,7 +36,8 @@
35 36
 }
36 37
 
37 38
 - (void)testInitWithLayoutInfo_shouldSetMultipleViewControllers {
38
-	self.uut = [[RNNNavigationController alloc] initWithLayoutInfo:nil creator:_creator childViewControllers:@[_vc1, _vc2] options:[[RNNNavigationOptions alloc] initWithDict:@{}] defaultOptions:nil presenter:[[RNNViewControllerPresenter alloc] init]];
39
+	self.uut = [[RNNNavigationController alloc] initWithLayoutInfo:nil creator:_creator options:[[RNNNavigationOptions alloc] initWithDict:@{}] defaultOptions:nil presenter:[[RNNViewControllerPresenter alloc] init] eventEmitter:nil];
40
+	[self.uut setViewControllers:@[_vc1, _vc2]];
39 41
 	XCTAssertTrue(self.uut.viewControllers.count == 2);
40 42
 }
41 43
 
@@ -153,7 +155,9 @@
153 155
 }
154 156
 
155 157
 - (RNNNavigationController *)createNavigationControllerWithOptions:(RNNNavigationOptions *)options {
156
-	return [[RNNNavigationController alloc] initWithLayoutInfo:nil creator:_creator childViewControllers:@[_vc1] options:options defaultOptions:nil presenter:[[RNNNavigationControllerPresenter alloc] init]];
158
+	RNNNavigationController* nav = [[RNNNavigationController alloc] initWithLayoutInfo:nil creator:_creator options:options defaultOptions:nil presenter:[[RNNNavigationControllerPresenter alloc] init] eventEmitter:nil];
159
+	[nav setViewControllers:@[_vc1]];
160
+	return nav;
157 161
 }
158 162
 
159 163
 @end

+ 11
- 6
lib/ios/ReactNativeNavigationTests/RNNRootViewControllerTest.m 查看文件

@@ -415,7 +415,8 @@
415 415
 -(void)testRightButtonsWithTitle_withoutStyle {
416 416
 	self.options.topBar.rightButtons = @[@{@"id": @"testId", @"text": @"test"}];
417 417
 	self.uut = [[RNNRootViewController alloc] initWithLayoutInfo:nil rootViewCreator:nil eventEmitter:nil presenter:[RNNViewControllerPresenter new] options:self.options defaultOptions:nil];
418
-	RNNNavigationController* nav = [[RNNNavigationController alloc] initWithLayoutInfo:nil creator:_creator childViewControllers:@[self.uut] options:nil defaultOptions:nil presenter:nil];
418
+	RNNNavigationController* nav = [[RNNNavigationController alloc] initWithLayoutInfo:nil creator:_creator options:nil defaultOptions:nil presenter:nil eventEmitter:nil];
419
+	[nav setViewControllers:@[self.uut]];
419 420
 
420 421
 	RNNUIBarButtonItem* button = (RNNUIBarButtonItem*)[nav.topViewController.navigationItem.rightBarButtonItems objectAtIndex:0];
421 422
 	NSString* expectedButtonId = @"testId";
@@ -430,7 +431,8 @@
430 431
 
431 432
 	self.options.topBar.rightButtons = @[@{@"id": @"testId", @"text": @"test", @"enabled": @false, @"buttonColor": inputColor, @"buttonFontSize": @22, @"buttonFontWeight": @"800"}];
432 433
 	self.uut = [[RNNRootViewController alloc] initWithLayoutInfo:nil rootViewCreator:nil eventEmitter:nil presenter:[RNNViewControllerPresenter new] options:self.options defaultOptions:nil];
433
-	RNNNavigationController* nav = [[RNNNavigationController alloc] initWithLayoutInfo:nil creator:_creator childViewControllers:@[self.uut] options:nil defaultOptions:nil presenter:nil];
434
+	RNNNavigationController* nav = [[RNNNavigationController alloc] initWithLayoutInfo:nil creator:_creator options:nil defaultOptions:nil presenter:nil eventEmitter:nil];
435
+	[nav setViewControllers:@[self.uut]];
434 436
 
435 437
 	RNNUIBarButtonItem* button = (RNNUIBarButtonItem*)[nav.topViewController.navigationItem.rightBarButtonItems objectAtIndex:0];
436 438
 	NSString* expectedButtonId = @"testId";
@@ -446,8 +448,9 @@
446 448
 -(void)testLeftButtonsWithTitle_withoutStyle {
447 449
 	self.options.topBar.leftButtons = @[@{@"id": @"testId", @"text": @"test"}];
448 450
 	self.uut = [[RNNRootViewController alloc] initWithLayoutInfo:nil rootViewCreator:nil eventEmitter:nil presenter:[RNNViewControllerPresenter new] options:self.options defaultOptions:nil];
449
-	RNNNavigationController* nav = [[RNNNavigationController alloc] initWithLayoutInfo:nil creator:_creator childViewControllers:@[self.uut] options:nil defaultOptions:nil presenter:nil];
450
-
451
+	RNNNavigationController* nav = [[RNNNavigationController alloc] initWithLayoutInfo:nil creator:_creator options:nil defaultOptions:nil presenter:nil eventEmitter:nil];
452
+	[nav setViewControllers:@[self.uut]];
453
+	
451 454
 	RNNUIBarButtonItem* button = (RNNUIBarButtonItem*)[nav.topViewController.navigationItem.leftBarButtonItems objectAtIndex:0];
452 455
 	NSString* expectedButtonId = @"testId";
453 456
 	NSString* expectedTitle = @"test";
@@ -461,7 +464,8 @@
461 464
 
462 465
 	self.options.topBar.leftButtons = @[@{@"id": @"testId", @"text": @"test", @"enabled": @false, @"buttonColor": inputColor, @"buttonFontSize": @22, @"buttonFontWeight": @"800"}];
463 466
 	self.uut = [[RNNRootViewController alloc] initWithLayoutInfo:nil rootViewCreator:nil eventEmitter:nil presenter:[RNNViewControllerPresenter new] options:self.options defaultOptions:nil];
464
-	RNNNavigationController* nav = [[RNNNavigationController alloc] initWithLayoutInfo:nil creator:_creator childViewControllers:@[self.uut] options:nil defaultOptions:nil presenter:nil];
467
+	RNNNavigationController* nav = [[RNNNavigationController alloc] initWithLayoutInfo:nil creator:_creator options:nil defaultOptions:nil presenter:nil eventEmitter:nil];
468
+	[nav setViewControllers:@[self.uut]];
465 469
 
466 470
 	RNNUIBarButtonItem* button = (RNNUIBarButtonItem*)[nav.topViewController.navigationItem.leftBarButtonItems objectAtIndex:0];
467 471
 	NSString* expectedButtonId = @"testId";
@@ -565,7 +569,8 @@
565 569
 
566 570
 
567 571
 - (RNNNavigationController *)createNavigationController {
568
-	RNNNavigationController* nav = [[RNNNavigationController alloc] initWithLayoutInfo:nil creator:nil childViewControllers:@[self.uut] options:[[RNNNavigationOptions alloc] initEmptyOptions] defaultOptions:nil presenter:[[RNNNavigationControllerPresenter alloc] init]];
572
+	RNNNavigationController* nav = [[RNNNavigationController alloc] initWithLayoutInfo:nil creator:nil options:[[RNNNavigationOptions alloc] initEmptyOptions] defaultOptions:nil presenter:[[RNNNavigationControllerPresenter alloc] init] eventEmitter:nil];
573
+	[nav setViewControllers:@[self.uut]];
569 574
 	
570 575
 	return nav;
571 576
 }

+ 1
- 1
lib/ios/ReactNativeNavigationTests/RNNSideMenuControllerTest.m 查看文件

@@ -16,7 +16,7 @@
16 16
 	_leftVC = [[RNNSideMenuChildVC alloc] initWithLayoutInfo:nil childViewControllers:@[[RNNRootViewController new]] options:nil defaultOptions:nil presenter:nil type:RNNSideMenuChildTypeLeft];
17 17
 	_rightVC = [[RNNSideMenuChildVC alloc] initWithLayoutInfo:nil childViewControllers:@[[RNNRootViewController new]] options:nil defaultOptions:nil presenter:nil type:RNNSideMenuChildTypeRight];
18 18
 	_centerVC = [[RNNSideMenuChildVC alloc] initWithLayoutInfo:nil childViewControllers:@[[RNNRootViewController new]] options:nil defaultOptions:nil presenter:nil type:RNNSideMenuChildTypeCenter];
19
-	self.uut = [[RNNSideMenuController alloc] initWithLayoutInfo:nil childViewControllers:@[_leftVC, _centerVC, _rightVC] options:[[RNNNavigationOptions alloc] initEmptyOptions] defaultOptions:nil presenter:nil];
19
+	self.uut = [[RNNSideMenuController alloc] initWithLayoutInfo:nil creator:nil childViewControllers:@[_leftVC, _centerVC, _rightVC] options:[[RNNNavigationOptions alloc] initEmptyOptions] defaultOptions:nil presenter:nil eventEmitter:nil];
20 20
 }
21 21
 
22 22
 - (void)testSetSideMenuWidthShouldUpdateLeftReactViewFrameWidth {

+ 0
- 11
lib/ios/ReactNativeNavigationTests/RNNStoreTest.m 查看文件

@@ -77,17 +77,6 @@
77 77
 	XCTAssertNil([self.store findComponentForId:vcId]);
78 78
 }
79 79
 
80
-
81
-- (void)testRemoveComponentByInstance {
82
-	NSString *componentId1 = @"cntId1";
83
-	UIViewController *vc1 = [UIViewController new];
84
-	
85
-	[self.store setComponent:vc1 componentId:componentId1];
86
-	[self.store removeComponentByViewControllerInstance:vc1];
87
-	
88
-	XCTAssertNil([self.store findComponentForId:@"cntId1"]);
89
-}
90
-
91 80
 - (void)testRemoveAllComponentsFromWindowShouldRemoveComponentsInWindow {
92 81
 	UIViewController* overlayVC = [self createMockedViewControllerWithWindow:[UIWindow new]];
93 82
 	

+ 11
- 6
lib/ios/ReactNativeNavigationTests/RNNTabBarControllerTest.m 查看文件

@@ -26,7 +26,8 @@
26 26
 	self.mockTabBarPresenter = [OCMockObject partialMockForObject:[[RNNTabBarPresenter alloc] init]];
27 27
 	self.mockChildViewController = [OCMockObject partialMockForObject:[RNNRootViewController new]];
28 28
 	self.mockEventEmmiter = [OCMockObject partialMockForObject:[RNNEventEmitter new]];
29
-	self.mockUut = [OCMockObject partialMockForObject:[[RNNTabBarController alloc] initWithLayoutInfo:nil childViewControllers:@[[[UIViewController alloc] init]] options:[[RNNNavigationOptions alloc] initWithDict:@{}] defaultOptions:nil presenter:self.mockTabBarPresenter eventEmitter:self.mockEventEmmiter]];
29
+	self.mockUut = [OCMockObject partialMockForObject:[[RNNTabBarController alloc] initWithLayoutInfo:nil creator:nil options:[[RNNNavigationOptions alloc] initWithDict:@{}] defaultOptions:nil presenter:self.mockTabBarPresenter eventEmitter:self.mockEventEmmiter]];
30
+	[self.mockUut setViewControllers:@[[[UIViewController alloc] init]]];
30 31
 	OCMStub([self.mockUut selectedViewController]).andReturn(self.mockChildViewController);
31 32
 }
32 33
 
@@ -38,7 +39,8 @@
38 39
 	UIViewController* vc1 = [[UIViewController alloc] init];
39 40
 	UIViewController* vc2 = [[UIViewController alloc] init];
40 41
 	
41
-	RNNTabBarController* uut = [[RNNTabBarController alloc] initWithLayoutInfo:nil childViewControllers:@[vc1, vc2] options:[[RNNNavigationOptions alloc] initWithDict:@{}] defaultOptions:nil presenter:[[RNNViewControllerPresenter alloc] init]];
42
+	RNNTabBarController* uut = [[RNNTabBarController alloc] initWithLayoutInfo:nil creator:nil options:[[RNNNavigationOptions alloc] initWithDict:@{}] defaultOptions:nil presenter:[[RNNViewControllerPresenter alloc] init] eventEmitter:nil];
43
+	[uut setViewControllers:@[vc1, vc2]];
42 44
 	XCTAssertTrue(uut.viewControllers.count == 2);
43 45
 }
44 46
 
@@ -48,7 +50,8 @@
48 50
 	RNNTabBarPresenter* presenter = [[RNNTabBarPresenter alloc] init];
49 51
 	NSArray* childViewControllers = @[[UIViewController new]];
50 52
 	
51
-	RNNTabBarController* uut = [[RNNTabBarController alloc] initWithLayoutInfo:layoutInfo childViewControllers:childViewControllers options:options defaultOptions:nil presenter:presenter];
53
+	RNNTabBarController* uut = [[RNNTabBarController alloc] initWithLayoutInfo:layoutInfo creator:nil options:options defaultOptions:nil presenter:presenter eventEmitter:nil];
54
+	[uut setViewControllers:childViewControllers];
52 55
 	XCTAssertTrue(uut.layoutInfo == layoutInfo);
53 56
 	XCTAssertTrue(uut.options == options);
54 57
 	XCTAssertTrue(uut.presenter == presenter);
@@ -63,7 +66,8 @@
63 66
 
64 67
 	NSArray* childViewControllers = @[[UIViewController new]];
65 68
 	
66
-	RNNTabBarController* uut = [[RNNTabBarController alloc] initWithLayoutInfo:layoutInfo childViewControllers:childViewControllers options:options defaultOptions:nil presenter:presenter eventEmitter:eventEmmiter];
69
+	RNNTabBarController* uut = [[RNNTabBarController alloc] initWithLayoutInfo:layoutInfo creator:nil options:options defaultOptions:nil presenter:presenter eventEmitter:eventEmmiter];
70
+	[uut setViewControllers:childViewControllers];
67 71
 	XCTAssertTrue(uut.layoutInfo == layoutInfo);
68 72
 	XCTAssertTrue(uut.options == options);
69 73
 	XCTAssertTrue(uut.presenter == presenter);
@@ -72,7 +76,7 @@
72 76
 }
73 77
 
74 78
 - (void)testInitWithLayoutInfo_shouldSetDelegate {
75
-	RNNTabBarController* uut = [[RNNTabBarController alloc] initWithLayoutInfo:nil childViewControllers:nil options:[[RNNNavigationOptions alloc] initWithDict:@{}] defaultOptions:nil presenter:[[RNNViewControllerPresenter alloc] init]];
79
+	RNNTabBarController* uut = [[RNNTabBarController alloc] initWithLayoutInfo:nil creator:nil options:[[RNNNavigationOptions alloc] initWithDict:@{}] defaultOptions:nil presenter:[[RNNBasePresenter alloc] init] eventEmitter:nil];
76 80
 	
77 81
 	XCTAssertTrue(uut.delegate == uut);
78 82
 }
@@ -148,7 +152,8 @@
148 152
 	
149 153
 	RNNRootViewController* vc = [[RNNRootViewController alloc] initWithLayoutInfo:layoutInfo rootViewCreator:nil eventEmitter:nil presenter:nil options:nil defaultOptions:nil];
150 154
 	
151
-	RNNTabBarController* uut = [[RNNTabBarController alloc] initWithLayoutInfo:nil childViewControllers:@[[UIViewController new], vc] options:nil defaultOptions:nil presenter:[RNNTabBarPresenter new]];
155
+	RNNTabBarController* uut = [[RNNTabBarController alloc] initWithLayoutInfo:nil creator:nil options:nil defaultOptions:nil presenter:[RNNTabBarPresenter new] eventEmitter:nil];
156
+	[uut setViewControllers:@[[UIViewController new], vc]];
152 157
 	[uut setSelectedIndexByComponentID:@"componentId"];
153 158
 	XCTAssertTrue(uut.selectedIndex == 1);
154 159
 }

+ 35
- 0
lib/ios/ReactNativeNavigationTests/UIViewController+LayoutProtocolTest.m 查看文件

@@ -0,0 +1,35 @@
1
+#import <XCTest/XCTest.h>
2
+#import <OCMock/OCMock.h>
3
+#import "UIViewController+LayoutProtocol.h"
4
+
5
+@interface UIViewController_LayoutProtocolTest : XCTestCase
6
+
7
+@property (nonatomic, retain) UIViewController* uut;
8
+
9
+@end
10
+
11
+@implementation UIViewController_LayoutProtocolTest
12
+
13
+- (void)setUp {
14
+	[super setUp];
15
+	self.uut = [OCMockObject partialMockForObject:[UIViewController new]];
16
+    self.uut.layoutInfo = [[RNNLayoutInfo alloc] init];
17
+    self.uut.layoutInfo.componentId = @"componentId";
18
+}
19
+
20
+- (void)testSetStoreShouldSaveComponent {
21
+    RNNStore* store = [[RNNStore alloc] init];
22
+    [self.uut setStore:store];
23
+    XCTAssertNotNil([store findComponentForId:self.uut.layoutInfo.componentId]);
24
+}
25
+
26
+- (void)testDeallocShouldRemoveComponentFromStore {
27
+    RNNStore* store = [[RNNStore alloc] init];
28
+    [self.uut setStore:store];
29
+    XCTAssertNotNil([store findComponentForId:self.uut.layoutInfo.componentId]);
30
+    self.uut = nil;
31
+    XCTAssertNil([store findComponentForId:self.uut.layoutInfo.componentId]);
32
+}
33
+
34
+
35
+@end

+ 30
- 0
lib/ios/UIViewController+LayoutProtocol.h 查看文件

@@ -0,0 +1,30 @@
1
+#import <UIKit/UIKit.h>
2
+#import "RNNEventEmitter.h"
3
+#import "RNNLayoutProtocol.h"
4
+#import "RNNStore.h"
5
+
6
+typedef void (^RNNReactViewReadyCompletionBlock)(void);
7
+
8
+@interface UIViewController (LayoutProtocol) <RNNLayoutProtocol>
9
+
10
+- (void)renderTreeAndWait:(BOOL)wait perform:(RNNReactViewReadyCompletionBlock)readyBlock;
11
+
12
+- (UIViewController *)getCurrentChild;
13
+
14
+- (void)mergeOptions:(RNNNavigationOptions *)options;
15
+
16
+- (RNNNavigationOptions *)resolveOptions;
17
+
18
+- (void)setDefaultOptions:(RNNNavigationOptions *)defaultOptions;
19
+
20
+- (void)overrideOptions:(RNNNavigationOptions *)options;
21
+
22
+@property (nonatomic, retain) RNNBasePresenter* presenter;
23
+@property (nonatomic, retain) RNNLayoutInfo* layoutInfo;
24
+@property (nonatomic, strong) RNNNavigationOptions* options;
25
+@property (nonatomic, strong) RNNNavigationOptions* defaultOptions;
26
+@property (nonatomic, strong) RNNEventEmitter* eventEmitter;
27
+@property (nonatomic, strong) RNNStore* store;
28
+@property (nonatomic) id<RNNRootViewCreator> creator;
29
+
30
+@end

+ 145
- 0
lib/ios/UIViewController+LayoutProtocol.m 查看文件

@@ -0,0 +1,145 @@
1
+
2
+#import "UIViewController+LayoutProtocol.h"
3
+#import <objc/runtime.h>
4
+
5
+@implementation UIViewController (LayoutProtocol)
6
+
7
+- (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo
8
+						   creator:(id<RNNRootViewCreator>)creator
9
+						   options:(RNNNavigationOptions *)options
10
+					defaultOptions:(RNNNavigationOptions *)defaultOptions
11
+						 presenter:(RNNBasePresenter *)presenter
12
+					  eventEmitter:(RNNEventEmitter *)eventEmitter {
13
+	self = [self init];
14
+	
15
+	self.options = options;
16
+	self.defaultOptions = defaultOptions;
17
+	self.layoutInfo = layoutInfo;
18
+	self.creator = creator;
19
+	self.eventEmitter = eventEmitter;
20
+	self.presenter = presenter;
21
+	[self.presenter bindViewController:self];
22
+	[self.presenter applyOptionsOnInit:self.options];
23
+
24
+	return self;
25
+}
26
+
27
+- (void)setStore:(RNNStore *)store {
28
+	objc_setAssociatedObject(self, @selector(store), store, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
29
+	[self.store setComponent:self componentId:self.layoutInfo.componentId];
30
+}
31
+
32
+- (RNNNavigationOptions *)resolveOptions {
33
+	return [(RNNNavigationOptions *)[self.options mergeInOptions:self.getCurrentChild.resolveOptions.copy] withDefault:self.defaultOptions];
34
+}
35
+
36
+- (void)mergeOptions:(RNNNavigationOptions *)options {
37
+	[self.presenter mergeOptions:options currentOptions:self.options defaultOptions:self.defaultOptions];
38
+	[((UIViewController *)self.parentViewController) mergeOptions:options];
39
+}
40
+
41
+- (void)overrideOptions:(RNNNavigationOptions *)options {
42
+	[self.options overrideOptions:options];
43
+}
44
+
45
+- (void)renderTreeAndWait:(BOOL)wait perform:(RNNReactViewReadyCompletionBlock)readyBlock {
46
+	dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
47
+		dispatch_group_t group = dispatch_group_create();
48
+		for (UIViewController* childViewController in self.childViewControllers) {
49
+			dispatch_group_enter(group);
50
+			dispatch_async(dispatch_get_main_queue(), ^{
51
+				[childViewController renderTreeAndWait:wait perform:^{
52
+					dispatch_group_leave(group);
53
+				}];
54
+			});
55
+		}
56
+		
57
+		dispatch_group_enter(group);
58
+		[self.presenter renderComponents:self.resolveOptions perform:^{
59
+			dispatch_group_leave(group);
60
+		}];
61
+		dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
62
+		
63
+		dispatch_async(dispatch_get_main_queue(), ^{
64
+			readyBlock();
65
+		});
66
+	});
67
+}
68
+
69
+- (UIViewController *)getCurrentChild {
70
+	return nil;
71
+}
72
+
73
+- (void)onChildWillAppear {
74
+	[self.presenter applyOptions:self.resolveOptions];
75
+	[((UISplitViewController *)self.parentViewController) onChildWillAppear];
76
+}
77
+
78
+- (void)willMoveToParentViewController:(UIViewController *)parent {
79
+	if (parent) {
80
+		[self.presenter applyOptionsOnWillMoveToParentViewController:self.resolveOptions];
81
+	}
82
+}
83
+
84
+- (void)dealloc {
85
+	[self.store removeComponent:self.layoutInfo.componentId];
86
+}
87
+
88
+
89
+#pragma mark getters and setters to associated object
90
+
91
+- (RNNNavigationOptions *)options {
92
+	return objc_getAssociatedObject(self, @selector(options));
93
+}
94
+
95
+- (void)setOptions:(RNNNavigationOptions *)options {
96
+	objc_setAssociatedObject(self, @selector(options), options, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
97
+}
98
+
99
+- (RNNNavigationOptions *)defaultOptions {
100
+	return objc_getAssociatedObject(self, @selector(defaultOptions));
101
+}
102
+
103
+- (void)setDefaultOptions:(RNNNavigationOptions *)defaultOptions {
104
+	objc_setAssociatedObject(self, @selector(defaultOptions), defaultOptions, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
105
+}
106
+
107
+- (RNNLayoutInfo *)layoutInfo {
108
+	return objc_getAssociatedObject(self, @selector(layoutInfo));
109
+}
110
+
111
+- (void)setLayoutInfo:(RNNLayoutInfo *)layoutInfo {
112
+	objc_setAssociatedObject(self, @selector(layoutInfo), layoutInfo, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
113
+}
114
+
115
+- (RNNBasePresenter *)presenter {
116
+	return objc_getAssociatedObject(self, @selector(presenter));
117
+}
118
+
119
+- (void)setPresenter:(RNNBasePresenter *)presenter {
120
+	objc_setAssociatedObject(self, @selector(presenter), presenter, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
121
+}
122
+
123
+- (RNNEventEmitter *)eventEmitter {
124
+	return objc_getAssociatedObject(self, @selector(eventEmitter));
125
+}
126
+
127
+- (void)setEventEmitter:(RNNEventEmitter *)eventEmitter {
128
+	objc_setAssociatedObject(self, @selector(eventEmitter), eventEmitter, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
129
+}
130
+
131
+- (RNNStore *)store {
132
+	return objc_getAssociatedObject(self, @selector(store));
133
+}
134
+
135
+- (id<RNNRootViewCreator>)creator {
136
+	return objc_getAssociatedObject(self, @selector(creator));
137
+}
138
+
139
+- (void)setCreator:(id<RNNRootViewCreator>)creator {
140
+	objc_setAssociatedObject(self, @selector(creator), creator, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
141
+}
142
+
143
+
144
+
145
+@end

+ 4
- 7
playground/src/screens/OverlayAlert.js 查看文件

@@ -2,6 +2,8 @@ const React = require('react');
2 2
 
3 3
 const { Text, Button, View, Alert, Platform } = require('react-native');
4 4
 const { Navigation } = require('react-native-navigation');
5
+const { component } = require('../commons/Layouts');
6
+const Screens = require('./Screens');
5 7
 
6 8
 const {
7 9
   OVERLAY_ALERT_HEADER,
@@ -23,13 +25,8 @@ class OverlayAlert extends React.PureComponent {
23 25
   }
24 26
 
25 27
   dismiss = () => Navigation.dismissOverlay(this.props.componentId);
26
-  setRoot = () => Navigation.setRoot({
27
-    root: {
28
-      component: {
29
-        name: 'navigation.playground.TextScreen'
30
-      }
31
-    }
32
-  });
28
+  setRoot = () => Navigation.setRoot({ root: component(Screens.Pushed) });
29
+
33 30
   setInterceptTouch = () => Navigation.mergeOptions(this.props.componentId, {
34 31
     overlay: {
35 32
       interceptTouchOutside: false