diff --git a/lib/ios/RNNBasePresenter.h b/lib/ios/RNNBasePresenter.h index 2b1157f39bc..ddda89f2afa 100644 --- a/lib/ios/RNNBasePresenter.h +++ b/lib/ios/RNNBasePresenter.h @@ -1,5 +1,7 @@ #import "RNNNavigationOptions.h" +typedef void (^RNNReactViewReadyCompletionBlock)(void); + @interface RNNBasePresenter : NSObject @property (nonatomic, weak) id bindedViewController; @@ -16,4 +18,6 @@ - (void)mergeOptions:(RNNNavigationOptions *)newOptions currentOptions:(RNNNavigationOptions *)currentOptions defaultOptions:(RNNNavigationOptions *)defaultOptions; +- (void)renderComponents:(RNNNavigationOptions *)options perform:(RNNReactViewReadyCompletionBlock)readyBlock; + @end diff --git a/lib/ios/RNNBasePresenter.m b/lib/ios/RNNBasePresenter.m index 3a8e73ed281..2227e726551 100644 --- a/lib/ios/RNNBasePresenter.m +++ b/lib/ios/RNNBasePresenter.m @@ -2,6 +2,7 @@ #import "UIViewController+RNNOptions.h" #import "RNNTabBarItemCreator.h" #import "RNNReactComponentRegistry.h" +#import "UIViewController+LayoutProtocol.h" @interface RNNBasePresenter () @property (nonatomic, strong) RNNReactComponentRegistry* componentRegistry; @@ -134,5 +135,11 @@ - (void)mergeOptions:(RNNNavigationOptions *)newOptions currentOptions:(RNNNavig } } +- (void)renderComponents:(RNNNavigationOptions *)options perform:(RNNReactViewReadyCompletionBlock)readyBlock { + if (readyBlock) { + readyBlock(); + readyBlock = nil; + } +} @end diff --git a/lib/ios/RNNCommandsHandler.m b/lib/ios/RNNCommandsHandler.m index f6bea937eaa..cb86b562159 100644 --- a/lib/ios/RNNCommandsHandler.m +++ b/lib/ios/RNNCommandsHandler.m @@ -8,6 +8,7 @@ #import "RNNDefaultOptionsHelper.h" #import "UIViewController+RNNOptions.h" #import "React/RCTI18nUtil.h" +#import "UIViewController+LayoutProtocol.h" static NSString* const setRoot = @"setRoot"; static NSString* const setStackRoot = @"setStackRoot"; @@ -73,9 +74,8 @@ - (void)setRoot:(NSDictionary*)layout commandId:(NSString*)commandId completion: } [_modalManager dismissAllModalsAnimated:NO]; - [_store removeAllComponentsFromWindow:_mainWindow]; - UIViewController *vc = [_controllerFactory createLayout:layout[@"root"]]; + UIViewController *vc = [_controllerFactory createLayout:layout[@"root"]]; [vc renderTreeAndWait:[vc.resolveOptions.animations.setRoot.waitForRender getWithDefaultValue:NO] perform:^{ _mainWindow.rootViewController = vc; @@ -114,7 +114,7 @@ - (void)setDefaultOptions:(NSDictionary*)optionsDict completion:(RNNTransitionCo - (void)push:(NSString*)componentId commandId:(NSString*)commandId layout:(NSDictionary*)layout completion:(RNNTransitionCompletionBlock)completion rejection:(RCTPromiseRejectBlock)rejection { [self assertReady]; - UIViewController *newVc = [_controllerFactory createLayout:layout]; + UIViewController *newVc = [_controllerFactory createLayout:layout]; UIViewController *fromVC = [_store findComponentForId:componentId]; if ([[newVc.resolveOptions.preview.reactTag getWithDefaultValue:@(0)] floatValue] > 0) { @@ -172,7 +172,7 @@ - (void)push:(NSString*)componentId commandId:(NSString*)commandId layout:(NSDic - (void)setStackRoot:(NSString*)componentId commandId:(NSString*)commandId children:(NSArray*)children completion:(RNNTransitionCompletionBlock)completion rejection:(RCTPromiseRejectBlock)rejection { [self assertReady]; - NSArray *childViewControllers = [_controllerFactory createChildrenLayout:children]; + NSArray *childViewControllers = [_controllerFactory createChildrenLayout:children]; for (UIViewController* viewController in childViewControllers) { [viewController renderTreeAndWait:NO perform:nil]; } @@ -207,7 +207,6 @@ - (void)pop:(NSString*)componentId commandId:(NSString*)commandId mergeOptions:( } [_stackManager pop:vc animated:[vc.resolveOptions.animations.pop.enable getWithDefaultValue:YES] completion:^{ - [_store removeComponent:componentId]; [_eventEmitter sendOnNavigationCommandCompletion:pop commandId:commandId params:@{@"componentId": componentId}]; completion(); } rejection:rejection]; @@ -221,7 +220,6 @@ - (void)popTo:(NSString*)componentId commandId:(NSString*)commandId mergeOptions [_stackManager popTo:vc animated:[vc.resolveOptions.animations.pop.enable getWithDefaultValue:YES] completion:^(NSArray *poppedViewControllers) { [_eventEmitter sendOnNavigationCommandCompletion:popTo commandId:commandId params:@{@"componentId": componentId}]; - [self removePopedViewControllers:poppedViewControllers]; completion(); } rejection:rejection]; } @@ -239,7 +237,7 @@ - (void)popToRoot:(NSString*)componentId commandId:(NSString*)commandId mergeOpt }]; [_stackManager popToRoot:vc animated:[vc.resolveOptions.animations.pop.enable getWithDefaultValue:YES] completion:^(NSArray *poppedViewControllers) { - [self removePopedViewControllers:poppedViewControllers]; + } rejection:^(NSString *code, NSString *message, NSError *error) { }]; @@ -250,7 +248,7 @@ - (void)popToRoot:(NSString*)componentId commandId:(NSString*)commandId mergeOpt - (void)showModal:(NSDictionary*)layout commandId:(NSString *)commandId completion:(RNNTransitionWithComponentIdCompletionBlock)completion { [self assertReady]; - UIViewController *newVc = [_controllerFactory createLayout:layout]; + UIViewController *newVc = [_controllerFactory createLayout:layout]; [newVc renderTreeAndWait:[newVc.resolveOptions.animations.showModal.waitForRender getWithDefaultValue:NO] perform:^{ [_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 @@ - (void)showModal:(NSDictionary*)layout commandId:(NSString *)commandId completi - (void)dismissModal:(NSString*)componentId commandId:(NSString*)commandId mergeOptions:(NSDictionary *)mergeOptions completion:(RNNTransitionCompletionBlock)completion rejection:(RNNTransitionRejectionBlock)reject { [self assertReady]; - UIViewController *modalToDismiss = (UIViewController*)[_store findComponentForId:componentId]; + UIViewController *modalToDismiss = (UIViewController *)[_store findComponentForId:componentId]; if (!modalToDismiss.isModal) { [RNNErrorHandler reject:reject withErrorCode:1013 errorDescription:@"component is not a modal"]; @@ -272,9 +270,7 @@ - (void)dismissModal:(NSString*)componentId commandId:(NSString*)commandId merge RNNNavigationOptions *options = [[RNNNavigationOptions alloc] initWithDict:mergeOptions]; [modalToDismiss.getCurrentChild overrideOptions:options]; - - [self removePopedViewControllers:modalToDismiss.navigationController.viewControllers]; - + [CATransaction begin]; [CATransaction setCompletionBlock:^{ [_eventEmitter sendOnNavigationCommandCompletion:dismissModal commandId:commandId params:@{@"componentId": componentId}]; @@ -302,7 +298,7 @@ - (void)dismissAllModals:(NSDictionary *)mergeOptions commandId:(NSString*)comma - (void)showOverlay:(NSDictionary *)layout commandId:(NSString*)commandId completion:(RNNTransitionCompletionBlock)completion { [self assertReady]; - UIViewController* overlayVC = [_controllerFactory createLayout:layout]; + UIViewController* overlayVC = [_controllerFactory createLayout:layout]; [overlayVC renderTreeAndWait:NO perform:^{ UIWindow* overlayWindow = [[RNNOverlayWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; overlayWindow.rootViewController = overlayVC; @@ -326,12 +322,6 @@ - (void)dismissOverlay:(NSString*)componentId commandId:(NSString*)commandId com #pragma mark - private -- (void)removePopedViewControllers:(NSArray*)viewControllers { - for (UIViewController *popedVC in viewControllers) { - [_store removeComponentByViewControllerInstance:popedVC]; - } -} - - (void)assertReady { if (!_store.isReadyToReceiveCommands) { [[NSException exceptionWithName:@"BridgeNotLoadedError" @@ -343,13 +333,13 @@ - (void)assertReady { #pragma mark - RNNModalManagerDelegate -- (void)dismissedModal:(UIViewController *)viewController { +- (void)dismissedModal:(UIViewController *)viewController { [_eventEmitter sendModalsDismissedEvent:viewController.layoutInfo.componentId numberOfModalsDismissed:@(1)]; } - (void)dismissedMultipleModals:(NSArray *)viewControllers { if (viewControllers && viewControllers.count) { - [_eventEmitter sendModalsDismissedEvent:((UIViewController *)viewControllers.lastObject).layoutInfo.componentId numberOfModalsDismissed:@(viewControllers.count)]; + [_eventEmitter sendModalsDismissedEvent:((UIViewController *)viewControllers.lastObject).layoutInfo.componentId numberOfModalsDismissed:@(viewControllers.count)]; } } diff --git a/lib/ios/RNNControllerFactory.h b/lib/ios/RNNControllerFactory.h index 65a5f737a22..9c97fc1f537 100644 --- a/lib/ios/RNNControllerFactory.h +++ b/lib/ios/RNNControllerFactory.h @@ -4,8 +4,8 @@ #import "RNNRootViewCreator.h" #import "RNNStore.h" #import "RNNEventEmitter.h" -#import "RNNParentProtocol.h" #import "RNNReactComponentRegistry.h" +#import "RNNNavigationOptions.h" @interface RNNControllerFactory : NSObject @@ -15,9 +15,9 @@ componentRegistry:(RNNReactComponentRegistry *)componentRegistry andBridge:(RCTBridge*)bridge; -- (UIViewController *)createLayout:(NSDictionary*)layout; +- (UIViewController *)createLayout:(NSDictionary*)layout; -- (NSArray *)createChildrenLayout:(NSArray*)children; +- (NSArray *)createChildrenLayout:(NSArray*)children; @property (nonatomic, strong) RNNEventEmitter *eventEmitter; diff --git a/lib/ios/RNNControllerFactory.m b/lib/ios/RNNControllerFactory.m index 7845c5f346b..d03ad42bbb6 100644 --- a/lib/ios/RNNControllerFactory.m +++ b/lib/ios/RNNControllerFactory.m @@ -43,8 +43,8 @@ - (instancetype)initWithRootViewCreator:(id )creator return self; } -- (UIViewController *)createLayout:(NSDictionary*)layout { - UIViewController* layoutViewController = [self fromTree:layout]; +- (UIViewController *)createLayout:(NSDictionary*)layout { + UIViewController* layoutViewController = [self fromTree:layout]; return layoutViewController; } @@ -58,10 +58,10 @@ - (instancetype)initWithRootViewCreator:(id )creator # pragma mark private -- (UIViewController *)fromTree:(NSDictionary*)json { +- (UIViewController *)fromTree:(NSDictionary*)json { RNNLayoutNode* node = [RNNLayoutNode create:json]; - UIViewController *result; + UIViewController *result; if (node.isComponent) { result = [self createComponent:node]; @@ -106,23 +106,23 @@ - (instancetype)initWithRootViewCreator:(id )creator if (!result) { @throw [NSException exceptionWithName:@"UnknownControllerType" reason:[@"Unknown controller type " stringByAppendingString:node.type] userInfo:nil]; } - - [_store setComponent:result componentId:node.nodeId]; + + result.store = _store; return result; } -- (UIViewController *)createComponent:(RNNLayoutNode*)node { +- (UIViewController *)createComponent:(RNNLayoutNode*)node { RNNLayoutInfo* layoutInfo = [[RNNLayoutInfo alloc] initWithNode:node]; RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:node.data[@"options"]];; RNNViewControllerPresenter* presenter = [[RNNViewControllerPresenter alloc] initWithComponentRegistry:_componentRegistry]; RNNRootViewController* component = [[RNNRootViewController alloc] initWithLayoutInfo:layoutInfo rootViewCreator:_creator eventEmitter:_eventEmitter presenter:presenter options:options defaultOptions:_defaultOptions]; - return (UIViewController *)component; + return (UIViewController *)component; } -- (UIViewController *)createExternalComponent:(RNNLayoutNode*)node { +- (UIViewController *)createExternalComponent:(RNNLayoutNode*)node { RNNLayoutInfo* layoutInfo = [[RNNLayoutInfo alloc] initWithNode:node]; RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:node.data[@"options"]];; RNNViewControllerPresenter* presenter = [[RNNViewControllerPresenter alloc] init]; @@ -132,61 +132,64 @@ - (instancetype)initWithRootViewCreator:(id )creator RNNRootViewController* component = [[RNNRootViewController alloc] initExternalComponentWithLayoutInfo:layoutInfo eventEmitter:_eventEmitter presenter:presenter options:options defaultOptions:_defaultOptions]; [component bindViewController:externalVC]; - return (UIViewController *)component; + return (UIViewController *)component; } -- (UIViewController *)createStack:(RNNLayoutNode*)node { +- (UIViewController *)createStack:(RNNLayoutNode*)node { RNNNavigationControllerPresenter* presenter = [[RNNNavigationControllerPresenter alloc] initWithComponentRegistry:_componentRegistry]; RNNLayoutInfo* layoutInfo = [[RNNLayoutInfo alloc] initWithNode:node]; RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:node.data[@"options"]];; NSArray *childViewControllers = [self extractChildrenViewControllersFromNode:node]; - RNNNavigationController* stack = [[RNNNavigationController alloc] initWithLayoutInfo:layoutInfo creator:_creator childViewControllers:childViewControllers options:options defaultOptions:_defaultOptions presenter:presenter]; + RNNNavigationController* stack = [[RNNNavigationController alloc] initWithLayoutInfo:layoutInfo creator:_creator options:options defaultOptions:_defaultOptions presenter:presenter eventEmitter:_eventEmitter]; + [stack setViewControllers:childViewControllers]; return stack; } --(UIViewController *)createTabs:(RNNLayoutNode*)node { +-(UIViewController *)createTabs:(RNNLayoutNode*)node { RNNLayoutInfo* layoutInfo = [[RNNLayoutInfo alloc] initWithNode:node]; RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:node.data[@"options"]];; RNNTabBarPresenter* presenter = [[RNNTabBarPresenter alloc] init]; NSArray *childViewControllers = [self extractChildrenViewControllersFromNode:node]; - RNNTabBarController* tabsController = [[RNNTabBarController alloc] initWithLayoutInfo:layoutInfo childViewControllers:childViewControllers options:options defaultOptions:_defaultOptions presenter:presenter eventEmitter:_eventEmitter]; + RNNTabBarController* tabsController = [[RNNTabBarController alloc] initWithLayoutInfo:layoutInfo creator:_creator options:options defaultOptions:_defaultOptions presenter:presenter eventEmitter:_eventEmitter]; + [tabsController setViewControllers:childViewControllers]; return tabsController; } -- (UIViewController *)createTopTabs:(RNNLayoutNode*)node { +- (UIViewController *)createTopTabs:(RNNLayoutNode*)node { RNNLayoutInfo* layoutInfo = [[RNNLayoutInfo alloc] initWithNode:node]; RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:node.data[@"options"]];; RNNViewControllerPresenter* presenter = [[RNNViewControllerPresenter alloc] init]; NSArray *childViewControllers = [self extractChildrenViewControllersFromNode:node]; - RNNTopTabsViewController* topTabsController = [[RNNTopTabsViewController alloc] initWithLayoutInfo:layoutInfo childViewControllers:childViewControllers options:options defaultOptions:_defaultOptions presenter:presenter]; + RNNTopTabsViewController* topTabsController = [[RNNTopTabsViewController alloc] initWithLayoutInfo:layoutInfo creator:_creator options:options defaultOptions:_defaultOptions presenter:presenter eventEmitter:_eventEmitter]; + [topTabsController setViewControllers:childViewControllers]; return topTabsController; } -- (UIViewController *)createSideMenu:(RNNLayoutNode*)node { +- (UIViewController *)createSideMenu:(RNNLayoutNode*)node { RNNLayoutInfo* layoutInfo = [[RNNLayoutInfo alloc] initWithNode:node]; RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:node.data[@"options"]];; RNNSideMenuPresenter* presenter = [[RNNSideMenuPresenter alloc] init]; NSArray *childViewControllers = [self extractChildrenViewControllersFromNode:node]; - RNNSideMenuController *sideMenu = [[RNNSideMenuController alloc] initWithLayoutInfo:layoutInfo childViewControllers:childViewControllers options:options defaultOptions:_defaultOptions presenter:presenter]; + RNNSideMenuController *sideMenu = [[RNNSideMenuController alloc] initWithLayoutInfo:layoutInfo creator:_creator childViewControllers:childViewControllers options:options defaultOptions:_defaultOptions presenter:presenter eventEmitter:_eventEmitter]; return sideMenu; } -- (UIViewController *)createSideMenuChild:(RNNLayoutNode*)node type:(RNNSideMenuChildType)type { - UIViewController* childVc = [self fromTree:node.children[0]]; +- (UIViewController *)createSideMenuChild:(RNNLayoutNode*)node type:(RNNSideMenuChildType)type { + UIViewController* childVc = [self fromTree:node.children[0]]; RNNLayoutInfo* layoutInfo = [[RNNLayoutInfo alloc] initWithNode:node]; RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:node.data[@"options"]];; @@ -195,15 +198,16 @@ - (instancetype)initWithRootViewCreator:(id )creator return sideMenuChild; } -- (UIViewController *)createSplitView:(RNNLayoutNode*)node { +- (UIViewController *)createSplitView:(RNNLayoutNode*)node { RNNLayoutInfo* layoutInfo = [[RNNLayoutInfo alloc] initWithNode:node]; RNNNavigationOptions* options = [[RNNNavigationOptions alloc] initWithDict:node.data[@"options"]];; RNNSplitViewControllerPresenter* presenter = [[RNNSplitViewControllerPresenter alloc] init]; NSArray *childViewControllers = [self extractChildrenViewControllersFromNode:node]; - RNNSplitViewController* splitViewController = [[RNNSplitViewController alloc] initWithLayoutInfo:layoutInfo childViewControllers:childViewControllers options:options defaultOptions:_defaultOptions presenter:presenter]; - + RNNSplitViewController* splitViewController = [[RNNSplitViewController alloc] initWithLayoutInfo:layoutInfo creator:_creator options:options defaultOptions:_defaultOptions presenter:presenter eventEmitter:_eventEmitter]; + [splitViewController bindChildViewControllers:childViewControllers]; + return splitViewController; } diff --git a/lib/ios/RNNLayoutProtocol.h b/lib/ios/RNNLayoutProtocol.h index 4318f37df6c..d21aceb0701 100644 --- a/lib/ios/RNNLayoutProtocol.h +++ b/lib/ios/RNNLayoutProtocol.h @@ -1,6 +1,7 @@ #import "RNNLayoutInfo.h" -#import "RNNLeafProtocol.h" #import "RNNBasePresenter.h" +#import "RNNRootViewCreator.h" +#import "RNNEventEmitter.h" typedef void (^RNNReactViewReadyCompletionBlock)(void); @@ -8,10 +9,12 @@ typedef void (^RNNReactViewReadyCompletionBlock)(void); @required -@property (nonatomic, retain) RNNBasePresenter* presenter; -@property (nonatomic, retain) RNNLayoutInfo* layoutInfo; -@property (nonatomic, strong) RNNNavigationOptions* options; -@property (nonatomic, strong) RNNNavigationOptions* defaultOptions; +- (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo + creator:(id)creator + options:(RNNNavigationOptions *)options + defaultOptions:(RNNNavigationOptions *)defaultOptions + presenter:(RNNBasePresenter *)presenter + eventEmitter:(RNNEventEmitter *)eventEmitter; - (void)renderTreeAndWait:(BOOL)wait perform:(RNNReactViewReadyCompletionBlock)readyBlock; @@ -25,4 +28,6 @@ typedef void (^RNNReactViewReadyCompletionBlock)(void); - (void)overrideOptions:(RNNNavigationOptions *)options; +- (void)onChildWillAppear; + @end diff --git a/lib/ios/RNNModalManager.m b/lib/ios/RNNModalManager.m index 41ea4b36b2f..18c0eb806e1 100644 --- a/lib/ios/RNNModalManager.m +++ b/lib/ios/RNNModalManager.m @@ -1,6 +1,7 @@ #import "RNNModalManager.h" #import "RNNRootViewController.h" #import "RNNAnimationsTransitionDelegate.h" +#import "RNNLayoutProtocol.h" @implementation RNNModalManager { NSMutableArray* _pendingModalIdsToDismiss; @@ -61,7 +62,7 @@ -(void)dismissAllModalsAnimated:(BOOL)animated { -(void)removePendingNextModalIfOnTop:(RNNTransitionCompletionBlock)completion { - UIViewController *modalToDismiss = [_pendingModalIdsToDismiss lastObject]; + UIViewController *modalToDismiss = [_pendingModalIdsToDismiss lastObject]; RNNNavigationOptions* options = modalToDismiss.resolveOptions; if(!modalToDismiss) { diff --git a/lib/ios/RNNNavigationButtons.m b/lib/ios/RNNNavigationButtons.m index 9f8c6ada4f9..c7cd267d25e 100644 --- a/lib/ios/RNNNavigationButtons.m +++ b/lib/ios/RNNNavigationButtons.m @@ -5,6 +5,7 @@ #import "UIImage+tint.h" #import "RNNRootViewController.h" #import "UIImage+insets.h" +#import "UIViewController+LayoutProtocol.h" @interface RNNNavigationButtons() diff --git a/lib/ios/RNNNavigationController.h b/lib/ios/RNNNavigationController.h index 2ac9fb095a2..6c0395fc282 100644 --- a/lib/ios/RNNNavigationController.h +++ b/lib/ios/RNNNavigationController.h @@ -1,17 +1,11 @@ #import -#import "RNNParentProtocol.h" #import "RNNNavigationControllerPresenter.h" #import "UINavigationController+RNNOptions.h" +#import "UIViewController+LayoutProtocol.h" -@interface RNNNavigationController : UINavigationController +@interface RNNNavigationController : UINavigationController -@property (nonatomic, retain) RNNLayoutInfo* layoutInfo; @property (nonatomic, retain) RNNNavigationControllerPresenter* presenter; -@property (nonatomic, strong) RNNNavigationOptions* options; -@property (nonatomic, strong) RNNNavigationOptions* defaultOptions; - - -- (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo creator:(id)creator childViewControllers:(NSArray *)childViewControllers options:(RNNNavigationOptions *)options defaultOptions:(RNNNavigationOptions *)defaultOptions presenter:(RNNBasePresenter *)presenter; - (void)setTopBarBackgroundColor:(UIColor *)backgroundColor; diff --git a/lib/ios/RNNNavigationController.m b/lib/ios/RNNNavigationController.m index e68c84f9ddc..4dfbac9c005 100644 --- a/lib/ios/RNNNavigationController.m +++ b/lib/ios/RNNNavigationController.m @@ -1,4 +1,3 @@ - #import "RNNNavigationController.h" #import "RNNRootViewController.h" #import "InteractivePopGestureDelegate.h" @@ -13,69 +12,9 @@ @interface RNNNavigationController() @implementation RNNNavigationController -- (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo creator:(id)creator childViewControllers:(NSArray *)childViewControllers options:(RNNNavigationOptions *)options defaultOptions:(RNNNavigationOptions *)defaultOptions presenter:(RNNNavigationControllerPresenter *)presenter { - self = [super init]; - - self.presenter = presenter; - [self.presenter bindViewController:self]; - - self.defaultOptions = defaultOptions; - self.options = options; - - self.layoutInfo = layoutInfo; - - [self setViewControllers:childViewControllers]; - - return self; -} - -- (void)willMoveToParentViewController:(UIViewController *)parent { - if (parent) { - [_presenter applyOptionsOnWillMoveToParentViewController:self.resolveOptions]; - } -} -- (void)onChildWillAppear { - [_presenter applyOptions:self.resolveOptions]; - [_presenter renderComponents:self.resolveOptions perform:nil]; - [((UIViewController *)self.parentViewController) onChildWillAppear]; -} - -- (RNNNavigationOptions *)resolveOptions { - return [(RNNNavigationOptions *)[self.options mergeInOptions:self.getCurrentChild.resolveOptions.copy] withDefault:self.defaultOptions]; -} - -- (void)mergeOptions:(RNNNavigationOptions *)options { - [_presenter mergeOptions:options currentOptions:self.options defaultOptions:self.defaultOptions]; - [((UIViewController *)self.parentViewController) mergeOptions:options]; -} - -- (void)overrideOptions:(RNNNavigationOptions *)options { - [self.options overrideOptions:options]; -} - -- (void)renderTreeAndWait:(BOOL)wait perform:(RNNReactViewReadyCompletionBlock)readyBlock { - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ - dispatch_group_t group = dispatch_group_create(); - for (UIViewController* childViewController in self.childViewControllers) { - dispatch_group_enter(group); - dispatch_async(dispatch_get_main_queue(), ^{ - [childViewController renderTreeAndWait:wait perform:^{ - dispatch_group_leave(group); - }]; - }); - } - - dispatch_group_enter(group); - [self.presenter renderComponents:self.resolveOptions perform:^{ - dispatch_group_leave(group); - }]; - dispatch_group_wait(group, DISPATCH_TIME_FOREVER); - - dispatch_async(dispatch_get_main_queue(), ^{ - readyBlock(); - }); - }); +- (UIViewController *)getCurrentChild { + return self.topViewController; } - (UIInterfaceOrientationMask)supportedInterfaceOrientations { @@ -106,10 +45,6 @@ - (UIViewController *)popViewControllerAnimated:(BOOL)animated { return [super popViewControllerAnimated:animated]; } -- (UIViewController *)getCurrentChild { - return ((UIViewController*)self.topViewController); -} - - (UIViewController *)childViewControllerForStatusBarStyle { return self.topViewController; } diff --git a/lib/ios/RNNNavigationControllerPresenter.h b/lib/ios/RNNNavigationControllerPresenter.h index a6a9696fb0c..4ccf47a2aee 100644 --- a/lib/ios/RNNNavigationControllerPresenter.h +++ b/lib/ios/RNNNavigationControllerPresenter.h @@ -11,6 +11,4 @@ - (void)applyOptionsBeforePopping:(RNNNavigationOptions *)options; -- (void)renderComponents:(RNNNavigationOptions *)options perform:(RNNReactViewReadyCompletionBlock)readyBlock; - @end diff --git a/lib/ios/RNNNavigationControllerPresenter.m b/lib/ios/RNNNavigationControllerPresenter.m index 9ac63918d52..f80b71ec6cb 100644 --- a/lib/ios/RNNNavigationControllerPresenter.m +++ b/lib/ios/RNNNavigationControllerPresenter.m @@ -3,6 +3,7 @@ #import "RNNNavigationController.h" #import #import "RNNCustomTitleView.h" +#import "UIViewController+LayoutProtocol.h" @interface RNNNavigationControllerPresenter() { RNNReactComponentRegistry* _componentRegistry; diff --git a/lib/ios/RNNParentProtocol.h b/lib/ios/RNNParentProtocol.h deleted file mode 100644 index 2e08597ad5c..00000000000 --- a/lib/ios/RNNParentProtocol.h +++ /dev/null @@ -1,13 +0,0 @@ -#import "RNNLayoutProtocol.h" -#import "RNNLeafProtocol.h" - -@protocol RNNParentProtocol - - -@optional -- (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo childViewControllers:(NSArray *)childViewControllers options:(RNNNavigationOptions *)options defaultOptions:(RNNNavigationOptions *)defaultOptions presenter:(RNNBasePresenter *)presenter; - -@required -- (void)onChildWillAppear; - -@end diff --git a/lib/ios/RNNRootViewController.h b/lib/ios/RNNRootViewController.h index 23561a9d6ba..e4fb8ec9c3c 100644 --- a/lib/ios/RNNRootViewController.h +++ b/lib/ios/RNNRootViewController.h @@ -5,13 +5,12 @@ #import "RNNAnimator.h" #import "RNNUIBarButtonItem.h" #import "RNNLayoutInfo.h" -#import "RNNLeafProtocol.h" #import "RNNLayoutProtocol.h" #import "RNNViewControllerPresenter.h" typedef void (^PreviewCallback)(UIViewController *vc); -@interface RNNRootViewController : UIViewController +@interface RNNRootViewController : UIViewController @property (nonatomic, strong) RNNEventEmitter *eventEmitter; @property (nonatomic, retain) RNNLayoutInfo* layoutInfo; @@ -19,7 +18,6 @@ typedef void (^PreviewCallback)(UIViewController *vc); @property (nonatomic, strong) RNNNavigationOptions* options; @property (nonatomic, strong) RNNNavigationOptions* defaultOptions; -@property (nonatomic) id creator; @property (nonatomic, strong) RNNAnimator* animator; @property (nonatomic, strong) UIViewController* previewController; @property (nonatomic, copy) PreviewCallback previewCallback; @@ -41,5 +39,6 @@ typedef void (^PreviewCallback)(UIViewController *vc); - (void)onButtonPress:(RNNUIBarButtonItem *)barButtonItem; +- (void)bindViewController:(UIViewController *)viewController; @end diff --git a/lib/ios/RNNRootViewController.m b/lib/ios/RNNRootViewController.m index dcead9ee81e..cb7f20905b5 100644 --- a/lib/ios/RNNRootViewController.m +++ b/lib/ios/RNNRootViewController.m @@ -3,26 +3,15 @@ #import "RNNAnimator.h" #import "RNNPushAnimation.h" #import "RNNReactView.h" -#import "RNNParentProtocol.h" #import "RNNAnimationsTransitionDelegate.h" +#import "UIViewController+LayoutProtocol.h" @implementation RNNRootViewController @synthesize previewCallback; - (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo rootViewCreator:(id)creator eventEmitter:(RNNEventEmitter *)eventEmitter presenter:(RNNViewControllerPresenter *)presenter options:(RNNNavigationOptions *)options defaultOptions:(RNNNavigationOptions *)defaultOptions { - self = [super init]; - - self.layoutInfo = layoutInfo; - self.creator = creator; - - self.eventEmitter = eventEmitter; - self.presenter = presenter; - [self.presenter bindViewController:self]; - self.options = options; - self.defaultOptions = defaultOptions; - - [self.presenter applyOptionsOnInit:self.resolveOptions]; + self = [super initWithLayoutInfo:layoutInfo creator:creator options:options defaultOptions:defaultOptions presenter:presenter eventEmitter:eventEmitter]; self.animator = [[RNNAnimator alloc] initWithTransitionOptions:self.resolveOptions.customTransition]; @@ -46,12 +35,6 @@ - (void)bindViewController:(UIViewController *)viewController { [viewController didMoveToParentViewController:self]; } -- (void)willMoveToParentViewController:(UIViewController *)parent { - if (parent) { - [_presenter applyOptionsOnWillMoveToParentViewController:self.resolveOptions]; - } -} - - (void)mergeOptions:(RNNNavigationOptions *)options { [_presenter mergeOptions:options currentOptions:self.options defaultOptions:self.defaultOptions]; [((UIViewController *)self.parentViewController) mergeOptions:options]; @@ -67,11 +50,7 @@ - (void)viewWillAppear:(BOOL)animated{ [_presenter applyOptions:self.resolveOptions]; [_presenter renderComponents:self.resolveOptions perform:nil]; - [((UIViewController *)self.parentViewController) onChildWillAppear]; -} - -- (RNNNavigationOptions *)resolveOptions { - return [self.options withDefault:self.defaultOptions]; + [((UIViewController *)self.parentViewController) onChildWillAppear]; } -(void)viewDidAppear:(BOOL)animated { @@ -97,7 +76,7 @@ - (void)renderTreeAndWait:(BOOL)wait perform:(RNNReactViewReadyCompletionBlock)r } __block RNNReactViewReadyCompletionBlock readyBlockCopy = readyBlock; - UIView* reactView = [_creator createRootView:self.layoutInfo.name rootViewId:self.layoutInfo.componentId availableSize:[UIScreen mainScreen].bounds.size reactViewReadyBlock:^{ + UIView* reactView = [self.creator createRootView:self.layoutInfo.name rootViewId:self.layoutInfo.componentId availableSize:[UIScreen mainScreen].bounds.size reactViewReadyBlock:^{ [_presenter renderComponents:self.resolveOptions perform:^{ if (readyBlockCopy) { readyBlockCopy(); @@ -115,7 +94,7 @@ - (void)renderTreeAndWait:(BOOL)wait perform:(RNNReactViewReadyCompletionBlock)r } - (UIViewController *)getCurrentChild { - return self; + return nil; } -(void)updateSearchResultsForSearchController:(UISearchController *)searchController { diff --git a/lib/ios/RNNSideMenuChildVC.h b/lib/ios/RNNSideMenuChildVC.h index a6ad9c7260c..df125172185 100644 --- a/lib/ios/RNNSideMenuChildVC.h +++ b/lib/ios/RNNSideMenuChildVC.h @@ -1,6 +1,6 @@ #import -#import "RNNParentProtocol.h" #import "RNNViewControllerPresenter.h" +#import "RNNLayoutProtocol.h" typedef NS_ENUM(NSInteger, RNNSideMenuChildType) { RNNSideMenuChildTypeCenter, @@ -9,15 +9,11 @@ typedef NS_ENUM(NSInteger, RNNSideMenuChildType) { }; -@interface RNNSideMenuChildVC : UIViewController +@interface RNNSideMenuChildVC : UIViewController @property (readonly) RNNSideMenuChildType type; @property (readonly) UIViewController *child; -@property (nonatomic, retain) RNNLayoutInfo* layoutInfo; -@property (nonatomic, retain) RNNViewControllerPresenter* presenter; -@property (nonatomic, strong) RNNNavigationOptions* options; -@property (nonatomic, strong) RNNNavigationOptions* defaultOptions; - (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo childViewControllers:(NSArray *)childViewControllers options:(RNNNavigationOptions *)options defaultOptions:(RNNNavigationOptions *)defaultOptions presenter:(RNNViewControllerPresenter *)presenter type:(RNNSideMenuChildType)type; diff --git a/lib/ios/RNNSideMenuChildVC.m b/lib/ios/RNNSideMenuChildVC.m index 2743613bf5e..ca2ee9ad241 100644 --- a/lib/ios/RNNSideMenuChildVC.m +++ b/lib/ios/RNNSideMenuChildVC.m @@ -1,5 +1,5 @@ #import "RNNSideMenuChildVC.h" - +#import "UIViewController+LayoutProtocol.h" @interface RNNSideMenuChildVC () @property (readwrite) RNNSideMenuChildType type; @@ -34,24 +34,6 @@ - (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo childViewControll return self; } -- (void)onChildWillAppear { - [_presenter applyOptions:self.resolveOptions]; - [((UIViewController *)self.parentViewController) onChildWillAppear]; -} - -- (RNNNavigationOptions *)resolveOptions { - return [(RNNNavigationOptions *)[self.options mergeInOptions:self.getCurrentChild.resolveOptions.copy] withDefault:self.defaultOptions]; -} - -- (void)mergeOptions:(RNNNavigationOptions *)options { - [_presenter mergeOptions:options currentOptions:self.options defaultOptions:self.defaultOptions]; - [((UIViewController *)self.parentViewController) mergeOptions:options]; -} - -- (void)overrideOptions:(RNNNavigationOptions *)options { - [self.options overrideOptions:options]; -} - - (void)renderTreeAndWait:(BOOL)wait perform:(RNNReactViewReadyCompletionBlock)readyBlock { [self.getCurrentChild renderTreeAndWait:wait perform:readyBlock]; } diff --git a/lib/ios/RNNSideMenuController.h b/lib/ios/RNNSideMenuController.h index b5bd80a2182..07df2a5c6fe 100644 --- a/lib/ios/RNNSideMenuController.h +++ b/lib/ios/RNNSideMenuController.h @@ -1,20 +1,17 @@ #import #import "RNNSideMenuChildVC.h" #import "MMDrawerController.h" -#import "RNNParentProtocol.h" -#import "RNNViewControllerPresenter.h" +#import "RNNSideMenuPresenter.h" +#import "UIViewController+LayoutProtocol.h" -@interface RNNSideMenuController : MMDrawerController +@interface RNNSideMenuController : MMDrawerController + +- (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo creator:(id)creator childViewControllers:(NSArray *)childViewControllers options:(RNNNavigationOptions *)options defaultOptions:(RNNNavigationOptions *)defaultOptions presenter:(RNNBasePresenter *)presenter eventEmitter:(RNNEventEmitter *)eventEmitter; @property (readonly) RNNSideMenuChildVC *center; @property (readonly) RNNSideMenuChildVC *left; @property (readonly) RNNSideMenuChildVC *right; -@property (nonatomic, retain) RNNLayoutInfo* layoutInfo; -@property (nonatomic, retain) RNNViewControllerPresenter* presenter; -@property (nonatomic, strong) RNNNavigationOptions* options; -@property (nonatomic, strong) RNNNavigationOptions* defaultOptions; - - (void)side:(MMDrawerSide)side enabled:(BOOL)enabled; - (void)side:(MMDrawerSide)side visible:(BOOL)visible; - (void)side:(MMDrawerSide)side width:(double)width; diff --git a/lib/ios/RNNSideMenuController.m b/lib/ios/RNNSideMenuController.m index 0e107690adc..9d6309bdcd6 100644 --- a/lib/ios/RNNSideMenuController.m +++ b/lib/ios/RNNSideMenuController.m @@ -13,7 +13,7 @@ @interface RNNSideMenuController () @implementation RNNSideMenuController -- (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo childViewControllers:(NSArray *)childViewControllers options:(RNNNavigationOptions *)options defaultOptions:(RNNNavigationOptions *)defaultOptions presenter:(RNNViewControllerPresenter *)presenter { +- (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo creator:(id)creator childViewControllers:(NSArray *)childViewControllers options:(RNNNavigationOptions *)options defaultOptions:(RNNNavigationOptions *)defaultOptions presenter:(RNNBasePresenter *)presenter eventEmitter:(RNNEventEmitter *)eventEmitter { [self setControllers:childViewControllers]; self = [super initWithCenterViewController:self.center leftDrawerViewController:self.left rightDrawerViewController:self.right]; @@ -36,50 +36,6 @@ - (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo childViewControll return self; } -- (void)willMoveToParentViewController:(UIViewController *)parent { - if (parent) { - [_presenter applyOptionsOnWillMoveToParentViewController:self.resolveOptions]; - } -} - -- (void)onChildWillAppear { - [_presenter applyOptions:self.resolveOptions]; - [((UIViewController *)self.parentViewController) onChildWillAppear]; -} - -- (RNNNavigationOptions *)resolveOptions { - return [(RNNNavigationOptions *)[self.options mergeInOptions:self.getCurrentChild.resolveOptions.copy] withDefault:self.defaultOptions]; -} - -- (void)mergeOptions:(RNNNavigationOptions *)options { - [_presenter mergeOptions:options currentOptions:self.options defaultOptions:self.defaultOptions]; - [((UIViewController *)self.parentViewController) mergeOptions:options]; -} - -- (void)overrideOptions:(RNNNavigationOptions *)options { - [self.options overrideOptions:options]; -} - -- (void)renderTreeAndWait:(BOOL)wait perform:(RNNReactViewReadyCompletionBlock)readyBlock { - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ - dispatch_group_t group = dispatch_group_create(); - for (UIViewController* childViewController in self.childViewControllers) { - dispatch_group_enter(group); - dispatch_async(dispatch_get_main_queue(), ^{ - [childViewController renderTreeAndWait:wait perform:^{ - dispatch_group_leave(group); - }]; - }); - } - - dispatch_group_wait(group, DISPATCH_TIME_FOREVER); - - dispatch_async(dispatch_get_main_queue(), ^{ - readyBlock(); - }); - }); -} - - (void)setAnimationType:(NSString *)animationType { MMDrawerControllerDrawerVisualStateBlock animationTypeStateBlock = nil; if ([animationType isEqualToString:@"door"]) animationTypeStateBlock = [MMDrawerVisualState swingingDoorVisualStateBlock]; diff --git a/lib/ios/RNNSplitViewController.h b/lib/ios/RNNSplitViewController.h index e6caa422b43..527675397ba 100644 --- a/lib/ios/RNNSplitViewController.h +++ b/lib/ios/RNNSplitViewController.h @@ -1,13 +1,10 @@ #import -#import "RNNParentProtocol.h" #import "RNNSplitViewControllerPresenter.h" #import "UISplitViewController+RNNOptions.h" +#import "RNNLayoutProtocol.h" -@interface RNNSplitViewController : UISplitViewController +@interface RNNSplitViewController : UISplitViewController -@property (nonatomic, strong) RNNNavigationOptions* options; -@property (nonatomic, strong) RNNNavigationOptions* defaultOptions; -@property (nonatomic, retain) RNNLayoutInfo* layoutInfo; -@property (nonatomic, retain) RNNSplitViewControllerPresenter* presenter; +- (void)bindChildViewControllers:(NSArray *> *)viewControllers; @end diff --git a/lib/ios/RNNSplitViewController.m b/lib/ios/RNNSplitViewController.m index 093a63117ea..dc9da965599 100644 --- a/lib/ios/RNNSplitViewController.m +++ b/lib/ios/RNNSplitViewController.m @@ -1,70 +1,8 @@ #import "RNNSplitViewController.h" +#import "UIViewController+LayoutProtocol.h" @implementation RNNSplitViewController -- (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo childViewControllers:(NSArray *)childViewControllers options:(RNNNavigationOptions *)options defaultOptions:(RNNNavigationOptions *)defaultOptions presenter:(RNNSplitViewControllerPresenter *)presenter { - self = [super init]; - - self.defaultOptions = defaultOptions; - self.options = options; - - self.presenter = presenter; - [self.presenter bindViewController:self]; - [self.presenter applyOptionsOnInit:self.options]; - - self.layoutInfo = layoutInfo; - - self.navigationController.delegate = self; - - [self bindChildViewControllers:childViewControllers]; - - return self; -} - -- (void)willMoveToParentViewController:(UIViewController *)parent { - if (parent) { - [_presenter applyOptionsOnWillMoveToParentViewController:self.resolveOptions]; - } -} - -- (void)onChildWillAppear { - [_presenter applyOptions:self.resolveOptions]; - [((UISplitViewController *)self.parentViewController) onChildWillAppear]; -} - -- (RNNNavigationOptions *)resolveOptions { - return [(RNNNavigationOptions *)[self.options mergeInOptions:self.getCurrentChild.resolveOptions.copy] withDefault:self.defaultOptions]; -} - -- (void)mergeOptions:(RNNNavigationOptions *)options { - [_presenter mergeOptions:options currentOptions:self.options defaultOptions:self.defaultOptions]; - [((UISplitViewController *)self.parentViewController) mergeOptions:options]; -} - -- (void)overrideOptions:(RNNNavigationOptions *)options { - [self.options overrideOptions:options]; -} - -- (void)renderTreeAndWait:(BOOL)wait perform:(RNNReactViewReadyCompletionBlock)readyBlock { - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ - dispatch_group_t group = dispatch_group_create(); - for (UIViewController* childViewController in self.childViewControllers) { - dispatch_group_enter(group); - dispatch_async(dispatch_get_main_queue(), ^{ - [childViewController renderTreeAndWait:wait perform:^{ - dispatch_group_leave(group); - }]; - }); - } - - dispatch_group_wait(group, DISPATCH_TIME_FOREVER); - - dispatch_async(dispatch_get_main_queue(), ^{ - readyBlock(); - }); - }); -} - - (void)bindChildViewControllers:(NSArray *> *)viewControllers { [self setViewControllers:viewControllers]; UIViewController* masterViewController = viewControllers[0]; diff --git a/lib/ios/RNNSplitViewOptions.m b/lib/ios/RNNSplitViewOptions.m index 34137672363..1043fd6c07d 100644 --- a/lib/ios/RNNSplitViewOptions.m +++ b/lib/ios/RNNSplitViewOptions.m @@ -1,5 +1,4 @@ #import "RNNSplitViewOptions.h" -#import "RNNParentProtocol.h" @implementation RNNSplitViewOptions diff --git a/lib/ios/RNNStore.h b/lib/ios/RNNStore.h index 6d1a7be1054..88e72d3abb0 100644 --- a/lib/ios/RNNStore.h +++ b/lib/ios/RNNStore.h @@ -1,8 +1,8 @@ #import #import -#import "RNNParentProtocol.h" #import "ReactNativeNavigation.h" +#import "RNNLayoutInfo.h" typedef void (^RNNTransitionCompletionBlock)(void); typedef void (^RNNTransitionWithComponentIdCompletionBlock)(NSString *componentId); @@ -13,7 +13,6 @@ typedef void (^RNNTransitionRejectionBlock)(NSString *code, NSString *message, N - (UIViewController*)findComponentForId:(NSString*)componentId; - (void)setComponent:(UIViewController*)viewController componentId:(NSString*)componentId; - (void)removeComponent:(NSString*)componentId; -- (void)removeComponentByViewControllerInstance:(UIViewController*)componentInstance; - (void)removeAllComponents; - (void)removeAllComponentsFromWindow:(UIWindow *)window; - (void)registerExternalComponent:(NSString *)name callback:(RNNExternalViewCreator)callback; diff --git a/lib/ios/RNNStore.m b/lib/ios/RNNStore.m index 220b0bed3a4..71a1fa83589 100644 --- a/lib/ios/RNNStore.m +++ b/lib/ios/RNNStore.m @@ -35,13 +35,6 @@ - (void)removeComponent:(NSString*)componentId { [_componentStore removeObjectForKey:componentId]; } -- (void)removeComponentByViewControllerInstance:(UIViewController*)componentInstance { - NSString *foundKey = [self componentKeyForInstance:componentInstance]; - if (foundKey) { - [self removeComponent:foundKey]; - } -} - - (void)removeAllComponents { [_componentStore removeAllObjects]; } diff --git a/lib/ios/RNNTabBarController.h b/lib/ios/RNNTabBarController.h index ee758895955..c6911a0c39b 100644 --- a/lib/ios/RNNTabBarController.h +++ b/lib/ios/RNNTabBarController.h @@ -1,18 +1,10 @@ #import -#import "RNNParentProtocol.h" #import "RNNEventEmitter.h" #import "RNNTabBarPresenter.h" +#import "UIViewController+LayoutProtocol.h" -@interface RNNTabBarController : UITabBarController - -- (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo childViewControllers:(NSArray *)childViewControllers options:(RNNNavigationOptions *)options defaultOptions:(RNNNavigationOptions *)defaultOptions presenter:(RNNTabBarPresenter *)presenter eventEmitter:(RNNEventEmitter *)eventEmitter; +@interface RNNTabBarController : UITabBarController - (void)setSelectedIndexByComponentID:(NSString *)componentID; -@property (nonatomic, retain) RNNLayoutInfo* layoutInfo; -@property (nonatomic, retain) RNNTabBarPresenter* presenter; -@property (nonatomic, strong) RNNNavigationOptions* options; -@property (nonatomic, strong) RNNNavigationOptions* defaultOptions; -@property (nonatomic, strong) RNNEventEmitter *eventEmitter; - @end diff --git a/lib/ios/RNNTabBarController.m b/lib/ios/RNNTabBarController.m index b6e102ced6a..7e543859e66 100644 --- a/lib/ios/RNNTabBarController.m +++ b/lib/ios/RNNTabBarController.m @@ -4,80 +4,12 @@ @implementation RNNTabBarController { NSUInteger _currentTabIndex; } -- (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo - childViewControllers:(NSArray *)childViewControllers - options:(RNNNavigationOptions *)options - defaultOptions:(RNNNavigationOptions *)defaultOptions - presenter:(RNNTabBarPresenter *)presenter - eventEmitter:(RNNEventEmitter *)eventEmitter { - self = [self initWithLayoutInfo:layoutInfo childViewControllers:childViewControllers options:options defaultOptions:defaultOptions presenter:presenter]; - - _eventEmitter = eventEmitter; - +- (id)delegate { return self; } -- (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo - childViewControllers:(NSArray *)childViewControllers - options:(RNNNavigationOptions *)options - defaultOptions:(RNNNavigationOptions *)defaultOptions - presenter:(RNNTabBarPresenter *)presenter { - self = [super init]; - - self.delegate = self; - self.options = options; - self.defaultOptions = defaultOptions; - self.layoutInfo = layoutInfo; - self.presenter = presenter; - [self.presenter bindViewController:self]; - [self setViewControllers:childViewControllers]; - [self.presenter applyOptionsOnInit:self.options]; - - return self; -} - -- (void)willMoveToParentViewController:(UIViewController *)parent { - if (parent) { - [_presenter applyOptionsOnWillMoveToParentViewController:self.resolveOptions]; - } -} - -- (void)onChildWillAppear { - [_presenter applyOptions:self.resolveOptions]; - [((UIViewController *)self.parentViewController) onChildWillAppear]; -} - -- (RNNNavigationOptions *)resolveOptions { - return [(RNNNavigationOptions *)[self.options mergeInOptions:self.getCurrentChild.resolveOptions.copy] withDefault:self.defaultOptions]; -} - -- (void)mergeOptions:(RNNNavigationOptions *)options { - [_presenter mergeOptions:options currentOptions:self.options defaultOptions:self.defaultOptions]; - [((UIViewController *)self.parentViewController) mergeOptions:options]; -} - -- (void)overrideOptions:(RNNNavigationOptions *)options { - [self.options overrideOptions:options]; -} - -- (void)renderTreeAndWait:(BOOL)wait perform:(RNNReactViewReadyCompletionBlock)readyBlock { - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ - dispatch_group_t group = dispatch_group_create(); - for (UIViewController* childViewController in self.childViewControllers) { - dispatch_group_enter(group); - dispatch_async(dispatch_get_main_queue(), ^{ - [childViewController renderTreeAndWait:wait perform:^{ - dispatch_group_leave(group); - }]; - }); - } - - dispatch_group_wait(group, DISPATCH_TIME_FOREVER); - - dispatch_async(dispatch_get_main_queue(), ^{ - readyBlock(); - }); - }); +- (UIViewController *)getCurrentChild { + return self.selectedViewController; } - (UIInterfaceOrientationMask)supportedInterfaceOrientations { @@ -99,18 +31,14 @@ - (void)setSelectedIndex:(NSUInteger)selectedIndex { [super setSelectedIndex:selectedIndex]; } -- (UIViewController *)getCurrentChild { - return self.selectedViewController; -} - - (UIStatusBarStyle)preferredStatusBarStyle { - return ((UIViewController*)self.selectedViewController).preferredStatusBarStyle; + return self.selectedViewController.preferredStatusBarStyle; } #pragma mark UITabBarControllerDelegate - (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController { - [_eventEmitter sendBottomTabSelected:@(tabBarController.selectedIndex) unselected:@(_currentTabIndex)]; + [self.eventEmitter sendBottomTabSelected:@(tabBarController.selectedIndex) unselected:@(_currentTabIndex)]; _currentTabIndex = tabBarController.selectedIndex; } diff --git a/lib/ios/RNNTopTabsViewController.h b/lib/ios/RNNTopTabsViewController.h index 08c8e7c4fbf..a938bcc95e5 100644 --- a/lib/ios/RNNTopTabsViewController.h +++ b/lib/ios/RNNTopTabsViewController.h @@ -1,15 +1,10 @@ #import -#import "RNNParentProtocol.h" +#import "RNNLayoutProtocol.h" -@interface RNNTopTabsViewController : UIViewController +@interface RNNTopTabsViewController : UIViewController @property (nonatomic, retain) UIView* contentView; -@property (nonatomic, retain) RNNLayoutInfo* layoutInfo; -@property (nonatomic, retain) RNNBasePresenter* presenter; -@property (nonatomic, strong) RNNNavigationOptions* options; -@property (nonatomic, strong) RNNNavigationOptions* defaultOptions; - - (void)setViewControllers:(NSArray*)viewControllers; - (void)viewController:(UIViewController*)vc changedTitle:(NSString*)title; - (instancetype)init; diff --git a/lib/ios/RNNTopTabsViewController.m b/lib/ios/RNNTopTabsViewController.m index 9e5bd1574fb..2c8bd35e0e7 100644 --- a/lib/ios/RNNTopTabsViewController.m +++ b/lib/ios/RNNTopTabsViewController.m @@ -2,10 +2,11 @@ #import "RNNSegmentedControl.h" #import "ReactNativeNavigation.h" #import "RNNRootViewController.h" +#import "UIViewController+LayoutProtocol.h" @interface RNNTopTabsViewController () { NSArray* _viewControllers; - UIViewController* _currentViewController; + UIViewController* _currentViewController; RNNSegmentedControl* _segmentedControl; } @@ -40,42 +41,8 @@ - (instancetype)init { return self; } -- (void)onChildWillAppear { - [_presenter applyOptions:self.resolveOptions]; - [((UIViewController *)self.parentViewController) onChildWillAppear]; -} - -- (RNNNavigationOptions *)resolveOptions { - return [(RNNNavigationOptions *)[self.options mergeInOptions:self.getCurrentChild.resolveOptions.copy] withDefault:self.defaultOptions]; -} - -- (void)mergeOptions:(RNNNavigationOptions *)options { - [_presenter mergeOptions:options currentOptions:self.options defaultOptions:self.defaultOptions]; - [((UIViewController *)self.parentViewController) mergeOptions:options]; -} - -- (void)overrideOptions:(RNNNavigationOptions *)options { - [self.options overrideOptions:options]; -} - -- (void)renderTreeAndWait:(BOOL)wait perform:(RNNReactViewReadyCompletionBlock)readyBlock { - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ - dispatch_group_t group = dispatch_group_create(); - for (UIViewController* childViewController in self.childViewControllers) { - dispatch_group_enter(group); - dispatch_async(dispatch_get_main_queue(), ^{ - [childViewController renderTreeAndWait:wait perform:^{ - dispatch_group_leave(group); - }]; - }); - } - - dispatch_group_wait(group, DISPATCH_TIME_FOREVER); - - dispatch_async(dispatch_get_main_queue(), ^{ - readyBlock(); - }); - }); +- (UIViewController *)getCurrentChild { + return _currentViewController; } - (void)createTabBar { @@ -100,7 +67,7 @@ - (void)createContentView { } - (void)setSelectedViewControllerIndex:(NSUInteger)index { - UIViewController *toVC = _viewControllers[index]; + UIViewController *toVC = _viewControllers[index]; [_contentView addSubview:toVC.view]; [_currentViewController.view removeFromSuperview]; _currentViewController = toVC; @@ -126,10 +93,4 @@ - (void)viewDidLoad { [super viewDidLoad]; } -#pragma mark RNNParentProtocol - -- (UIViewController *)getCurrentChild { - return _currentViewController; -} - @end diff --git a/lib/ios/RNNViewControllerPresenter.m b/lib/ios/RNNViewControllerPresenter.m index 11f2c458314..7babcb8591b 100644 --- a/lib/ios/RNNViewControllerPresenter.m +++ b/lib/ios/RNNViewControllerPresenter.m @@ -5,6 +5,7 @@ #import "RNNReactView.h" #import "RNNCustomTitleView.h" #import "RNNTitleViewHelper.h" +#import "UIViewController+LayoutProtocol.h" @interface RNNViewControllerPresenter() { RNNReactView* _customTitleView; diff --git a/lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj b/lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj index 531e6a345f3..cc4411fbfea 100644 --- a/lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj +++ b/lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj @@ -205,7 +205,6 @@ 507F43F51FF4FCFE00D9425B /* HMSegmentedControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 507F43F31FF4FCFE00D9425B /* HMSegmentedControl.m */; }; 507F43F81FF525B500D9425B /* RNNSegmentedControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 507F43F61FF525B500D9425B /* RNNSegmentedControl.h */; }; 507F43F91FF525B500D9425B /* RNNSegmentedControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 507F43F71FF525B500D9425B /* RNNSegmentedControl.m */; }; - 507F44201FFA8A8800D9425B /* RNNParentProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 507F441F1FFA8A8800D9425B /* RNNParentProtocol.h */; }; 5085DD2D21DCF75A0032E64B /* RNNSideMenuControllerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 5085DD2C21DCF75A0032E64B /* RNNSideMenuControllerTest.m */; }; 50887C1520ECC5C200D06111 /* RNNButtonOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 50887C1320ECC5C200D06111 /* RNNButtonOptions.h */; }; 50887C1620ECC5C200D06111 /* RNNButtonOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 50887C1420ECC5C200D06111 /* RNNButtonOptions.m */; }; @@ -215,6 +214,9 @@ 509B258F2178BE7A00C83C23 /* RNNNavigationControllerPresenterTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 509B258E2178BE7A00C83C23 /* RNNNavigationControllerPresenterTest.m */; }; 50A00C37200F84D6000F01A6 /* RNNOverlayOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 50A00C35200F84D6000F01A6 /* RNNOverlayOptions.h */; }; 50A00C38200F84D6000F01A6 /* RNNOverlayOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 50A00C36200F84D6000F01A6 /* RNNOverlayOptions.m */; }; + 50AB0B1C2255F8640039DAED /* UIViewController+LayoutProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 50AB0B1A2255F8640039DAED /* UIViewController+LayoutProtocol.h */; }; + 50AB0B1D2255F8640039DAED /* UIViewController+LayoutProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = 50AB0B1B2255F8640039DAED /* UIViewController+LayoutProtocol.m */; }; + 50AB0B1F22562FA10039DAED /* UIViewController+LayoutProtocolTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 50AB0B1E22562FA10039DAED /* UIViewController+LayoutProtocolTest.m */; }; 50BE951220B5A787004F5DF5 /* RNNStatusBarOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 50BE951020B5A787004F5DF5 /* RNNStatusBarOptions.m */; }; 50BE951320B5A787004F5DF5 /* RNNStatusBarOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 50BE951120B5A787004F5DF5 /* RNNStatusBarOptions.h */; }; 50C4A496206BDDBB00DB292E /* RNNSubtitleOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 50C4A494206BDDBB00DB292E /* RNNSubtitleOptions.h */; }; @@ -542,7 +544,6 @@ 507F43F31FF4FCFE00D9425B /* HMSegmentedControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HMSegmentedControl.m; sourceTree = ""; }; 507F43F61FF525B500D9425B /* RNNSegmentedControl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNSegmentedControl.h; sourceTree = ""; }; 507F43F71FF525B500D9425B /* RNNSegmentedControl.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNSegmentedControl.m; sourceTree = ""; }; - 507F441F1FFA8A8800D9425B /* RNNParentProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNNParentProtocol.h; sourceTree = ""; }; 5085DD2C21DCF75A0032E64B /* RNNSideMenuControllerTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNSideMenuControllerTest.m; sourceTree = ""; }; 50887C1320ECC5C200D06111 /* RNNButtonOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNButtonOptions.h; sourceTree = ""; }; 50887C1420ECC5C200D06111 /* RNNButtonOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNButtonOptions.m; sourceTree = ""; }; @@ -552,6 +553,9 @@ 509B258E2178BE7A00C83C23 /* RNNNavigationControllerPresenterTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNNavigationControllerPresenterTest.m; sourceTree = ""; }; 50A00C35200F84D6000F01A6 /* RNNOverlayOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNOverlayOptions.h; sourceTree = ""; }; 50A00C36200F84D6000F01A6 /* RNNOverlayOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNOverlayOptions.m; sourceTree = ""; }; + 50AB0B1A2255F8640039DAED /* UIViewController+LayoutProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UIViewController+LayoutProtocol.h"; sourceTree = ""; }; + 50AB0B1B2255F8640039DAED /* UIViewController+LayoutProtocol.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIViewController+LayoutProtocol.m"; sourceTree = ""; }; + 50AB0B1E22562FA10039DAED /* UIViewController+LayoutProtocolTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIViewController+LayoutProtocolTest.m"; sourceTree = ""; }; 50BE951020B5A787004F5DF5 /* RNNStatusBarOptions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNNStatusBarOptions.m; sourceTree = ""; }; 50BE951120B5A787004F5DF5 /* RNNStatusBarOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNNStatusBarOptions.h; sourceTree = ""; }; 50C4A494206BDDBB00DB292E /* RNNSubtitleOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNSubtitleOptions.h; sourceTree = ""; }; @@ -824,9 +828,10 @@ 5012242D2173E0E0000F5F98 /* Protocols */ = { isa = PBXGroup; children = ( - 507F441F1FFA8A8800D9425B /* RNNParentProtocol.h */, 505EDD33214E7A6A0071C7DE /* RNNLeafProtocol.h */, 505EDD47214FC4A60071C7DE /* RNNLayoutProtocol.h */, + 50AB0B1A2255F8640039DAED /* UIViewController+LayoutProtocol.h */, + 50AB0B1B2255F8640039DAED /* UIViewController+LayoutProtocol.m */, ); name = Protocols; sourceTree = ""; @@ -1076,6 +1081,7 @@ 502F0E132178CF8200367CC3 /* UIViewController+RNNOptionsTest.m */, 5038A376216CF252009280BC /* UITabBarController+RNNOptionsTest.m */, 509B247F217873FF00C83C23 /* UINavigationController+RNNOptionsTest.m */, + 50AB0B1E22562FA10039DAED /* UIViewController+LayoutProtocolTest.m */, ); path = ReactNativeNavigationTests; sourceTree = ""; @@ -1279,6 +1285,7 @@ E8DA24401F97459B00CD552B /* RNNElementFinder.h in Headers */, 263905BE1E4C6F440023D7D3 /* RCCTheSideBarManagerViewController.h in Headers */, 263905CE1E4C6F440023D7D3 /* TheSidebarController.h in Headers */, + 50AB0B1C2255F8640039DAED /* UIViewController+LayoutProtocol.h in Headers */, 50D031342005149000386B3D /* RNNOverlayManager.h in Headers */, 50E5F7952240EBD6002AFEAD /* RNNAnimationsTransitionDelegate.h in Headers */, 7B1126A71E2D2B6C00F9B03B /* RNNEventEmitter.h in Headers */, @@ -1295,7 +1302,6 @@ 50E5F791223FA04C002AFEAD /* RNNAnimationConfigurationOptions.h in Headers */, 5049594E216F6277006D2B81 /* NumberParser.h in Headers */, 50BE951320B5A787004F5DF5 /* RNNStatusBarOptions.h in Headers */, - 507F44201FFA8A8800D9425B /* RNNParentProtocol.h in Headers */, 50570BEA2063E09B006A1B5C /* RNNTitleViewHelper.h in Headers */, 263905CA1E4C6F440023D7D3 /* SidebarLuvocracyAnimation.h in Headers */, 50495956216F6B3D006D2B81 /* DictionaryParser.h in Headers */, @@ -1446,6 +1452,7 @@ 5038A379216D01F6009280BC /* RNNBottomTabOptionsTest.m in Sources */, E83BAD681F2734B500A9F3DD /* RNNNavigationOptionsTest.m in Sources */, 505EDD32214E4BE80071C7DE /* RNNNavigationControllerTest.m in Sources */, + 50AB0B1F22562FA10039DAED /* UIViewController+LayoutProtocolTest.m in Sources */, 7B49FECF1E95098500DEB3EA /* RNNNavigationStackManagerTest.m in Sources */, 509B2480217873FF00C83C23 /* UINavigationController+RNNOptionsTest.m in Sources */, 506F630D216A599300AD0D0A /* RNNTabBarControllerTest.m in Sources */, @@ -1467,6 +1474,7 @@ files = ( 263905C71E4C6F440023D7D3 /* SidebarFeedlyAnimation.m in Sources */, 50C4A497206BDDBB00DB292E /* RNNSubtitleOptions.m in Sources */, + 50AB0B1D2255F8640039DAED /* UIViewController+LayoutProtocol.m in Sources */, 263905B41E4C6F440023D7D3 /* MMDrawerVisualState.m in Sources */, 5012240B21735959000F5F98 /* RNNSideMenuPresenter.m in Sources */, 502CB46F20CD1DDA0019B2FE /* RNNBackButtonOptions.m in Sources */, diff --git a/lib/ios/ReactNativeNavigationTests/RNNCommandsHandlerTest.m b/lib/ios/ReactNativeNavigationTests/RNNCommandsHandlerTest.m index d8d0cdb576d..f5a68706b77 100644 --- a/lib/ios/ReactNativeNavigationTests/RNNCommandsHandlerTest.m +++ b/lib/ios/ReactNativeNavigationTests/RNNCommandsHandlerTest.m @@ -122,21 +122,22 @@ -(void)testDynamicStylesMergeWithStaticStyles { initialOptions.topBar.title.text = [[Text alloc] initWithValue:@"the title"]; RNNLayoutInfo* layoutInfo = [RNNLayoutInfo new]; RNNTestRootViewCreator* creator = [[RNNTestRootViewCreator alloc] init]; - + RNNViewControllerPresenter* presenter = [[RNNViewControllerPresenter alloc] init]; RNNRootViewController* vc = [[RNNRootViewController alloc] initWithLayoutInfo:layoutInfo rootViewCreator:creator eventEmitter:nil presenter:presenter options:initialOptions defaultOptions:nil]; - - RNNNavigationController* nav = [[RNNNavigationController alloc] initWithLayoutInfo:nil creator:creator childViewControllers:@[vc] options:[[RNNNavigationOptions alloc] initEmptyOptions] defaultOptions:nil presenter:[[RNNNavigationControllerPresenter alloc] init]]; + + RNNNavigationController* nav = [[RNNNavigationController alloc] initWithLayoutInfo:nil creator:creator options:[[RNNNavigationOptions alloc] initEmptyOptions] defaultOptions:nil presenter:[[RNNNavigationControllerPresenter alloc] init] eventEmitter:nil]; + [nav setViewControllers:@[vc]]; [vc viewWillAppear:false]; XCTAssertTrue([vc.navigationItem.title isEqual:@"the title"]); - + [self.store setReadyToReceiveCommands:true]; [self.store setComponent:vc componentId:@"componentId"]; - + NSDictionary* dictFromJs = @{@"topBar": @{@"background" : @{@"color" : @(0xFFFF0000)}}}; UIColor* expectedColor = [UIColor colorWithRed:1 green:0 blue:0 alpha:1]; - + [self.uut mergeOptions:@"componentId" options:dictFromJs completion:^{ XCTAssertTrue([vc.navigationItem.title isEqual:@"the title"]); XCTAssertTrue([nav.navigationBar.barTintColor isEqual:expectedColor]); @@ -164,50 +165,6 @@ - (void)testMergeOptions_shouldOverrideOptions { }]; } -- (void)testPop_removeTopVCFromStore { - [self.store setReadyToReceiveCommands:true]; - XCTestExpectation *expectation = [self expectationWithDescription:@"Testing Async Method"]; - - [self.uut pop:@"vc3" commandId:@"" mergeOptions:nil completion:^{ - XCTAssertNil([self.store findComponentForId:@"vc3"]); - XCTAssertNotNil([self.store findComponentForId:@"vc2"]); - XCTAssertNotNil([self.store findComponentForId:@"vc1"]); - [expectation fulfill]; - } rejection:^(NSString *code, NSString *message, NSError *error) { - - }]; - - [self waitForExpectationsWithTimeout:1 handler:nil]; -} - -- (void)testPopToSpecificVC_removeAllPopedVCFromStore { - [self.store setReadyToReceiveCommands:true]; - XCTestExpectation *expectation = [self expectationWithDescription:@"Testing Async Method"]; - _nvc.willReturnVCs = @[self.vc2, self.vc3]; - [self.uut popTo:@"vc1" commandId:@"" mergeOptions:nil completion:^{ - XCTAssertNil([self.store findComponentForId:@"vc2"]); - XCTAssertNil([self.store findComponentForId:@"vc3"]); - XCTAssertNotNil([self.store findComponentForId:@"vc1"]); - [expectation fulfill]; - } rejection:nil]; - - [self waitForExpectationsWithTimeout:1 handler:nil]; -} - -- (void)testPopToRoot_removeAllTopVCsFromStore { - [self.store setReadyToReceiveCommands:true]; - _nvc.willReturnVCs = @[self.vc2, self.vc3]; - XCTestExpectation *expectation = [self expectationWithDescription:@"Testing Async Method"]; - [self.uut popToRoot:@"vc3" commandId:@"" mergeOptions:nil completion:^{ - XCTAssertNil([self.store findComponentForId:@"vc2"]); - XCTAssertNil([self.store findComponentForId:@"vc3"]); - XCTAssertNotNil([self.store findComponentForId:@"vc1"]); - [expectation fulfill]; - } rejection:nil]; - - [self waitForExpectationsWithTimeout:1 handler:nil]; -} - - (void)testShowOverlay_createLayout { [self.store setReadyToReceiveCommands:true]; OCMStub([self.overlayManager showOverlayWindow:[OCMArg any]]); @@ -302,15 +259,6 @@ - (void)testSetRoot_setRootViewControllerOnMainWindow { [self.mainWindow verify]; } -- (void)testSetRoot_removeAllComponentsFromMainWindow { - [self.store setReadyToReceiveCommands:true]; - OCMStub([self.controllerFactory createLayout:[OCMArg any]]).andReturn(self.vc1); - - [[self.store expect] removeAllComponentsFromWindow:self.mainWindow]; - [self.uut setRoot:@{} commandId:@"" completion:^{}]; - [self.store verify]; -} - - (void)testSetStackRoot_resetStackWithSingleComponent { OCMStub([self.controllerFactory createChildrenLayout:[OCMArg any]]).andReturn(@[self.vc2]); [self.store setReadyToReceiveCommands:true]; diff --git a/lib/ios/ReactNativeNavigationTests/RNNNavigationControllerTest.m b/lib/ios/ReactNativeNavigationTests/RNNNavigationControllerTest.m index d95e11042d9..b3706fbac0a 100644 --- a/lib/ios/ReactNativeNavigationTests/RNNNavigationControllerTest.m +++ b/lib/ios/ReactNativeNavigationTests/RNNNavigationControllerTest.m @@ -27,7 +27,8 @@ - (void)setUp { _vc2Mock = [OCMockObject partialMockForObject:_vc2]; _vc3 = [UIViewController new]; _options = [OCMockObject partialMockForObject:[[RNNNavigationOptions alloc] initEmptyOptions]]; - self.uut = [[RNNNavigationController alloc] initWithLayoutInfo:nil creator:_creator childViewControllers:@[_vc1, _vc2] options:_options defaultOptions:nil presenter:[OCMockObject partialMockForObject:[[RNNNavigationControllerPresenter alloc] init]]]; + self.uut = [[RNNNavigationController alloc] initWithLayoutInfo:nil creator:_creator options:_options defaultOptions:nil presenter:[OCMockObject partialMockForObject:[[RNNNavigationControllerPresenter alloc] init]] eventEmitter:nil]; + [self.uut setViewControllers:@[_vc1, _vc2]]; } - (void)testInitWithLayoutInfo_shouldBindPresenter { @@ -35,7 +36,8 @@ - (void)testInitWithLayoutInfo_shouldBindPresenter { } - (void)testInitWithLayoutInfo_shouldSetMultipleViewControllers { - self.uut = [[RNNNavigationController alloc] initWithLayoutInfo:nil creator:_creator childViewControllers:@[_vc1, _vc2] options:[[RNNNavigationOptions alloc] initWithDict:@{}] defaultOptions:nil presenter:[[RNNViewControllerPresenter alloc] init]]; + self.uut = [[RNNNavigationController alloc] initWithLayoutInfo:nil creator:_creator options:[[RNNNavigationOptions alloc] initWithDict:@{}] defaultOptions:nil presenter:[[RNNViewControllerPresenter alloc] init] eventEmitter:nil]; + [self.uut setViewControllers:@[_vc1, _vc2]]; XCTAssertTrue(self.uut.viewControllers.count == 2); } @@ -153,7 +155,9 @@ - (void)testOverrideOptionsShouldOverrideOptionsState { } - (RNNNavigationController *)createNavigationControllerWithOptions:(RNNNavigationOptions *)options { - return [[RNNNavigationController alloc] initWithLayoutInfo:nil creator:_creator childViewControllers:@[_vc1] options:options defaultOptions:nil presenter:[[RNNNavigationControllerPresenter alloc] init]]; + RNNNavigationController* nav = [[RNNNavigationController alloc] initWithLayoutInfo:nil creator:_creator options:options defaultOptions:nil presenter:[[RNNNavigationControllerPresenter alloc] init] eventEmitter:nil]; + [nav setViewControllers:@[_vc1]]; + return nav; } @end diff --git a/lib/ios/ReactNativeNavigationTests/RNNRootViewControllerTest.m b/lib/ios/ReactNativeNavigationTests/RNNRootViewControllerTest.m index c7737a2b15d..43bf3d756e1 100644 --- a/lib/ios/ReactNativeNavigationTests/RNNRootViewControllerTest.m +++ b/lib/ios/ReactNativeNavigationTests/RNNRootViewControllerTest.m @@ -415,7 +415,8 @@ -(void)testOrientationTabsController_all { -(void)testRightButtonsWithTitle_withoutStyle { self.options.topBar.rightButtons = @[@{@"id": @"testId", @"text": @"test"}]; self.uut = [[RNNRootViewController alloc] initWithLayoutInfo:nil rootViewCreator:nil eventEmitter:nil presenter:[RNNViewControllerPresenter new] options:self.options defaultOptions:nil]; - RNNNavigationController* nav = [[RNNNavigationController alloc] initWithLayoutInfo:nil creator:_creator childViewControllers:@[self.uut] options:nil defaultOptions:nil presenter:nil]; + RNNNavigationController* nav = [[RNNNavigationController alloc] initWithLayoutInfo:nil creator:_creator options:nil defaultOptions:nil presenter:nil eventEmitter:nil]; + [nav setViewControllers:@[self.uut]]; RNNUIBarButtonItem* button = (RNNUIBarButtonItem*)[nav.topViewController.navigationItem.rightBarButtonItems objectAtIndex:0]; NSString* expectedButtonId = @"testId"; @@ -430,7 +431,8 @@ -(void)testRightButtonsWithTitle_withStyle { self.options.topBar.rightButtons = @[@{@"id": @"testId", @"text": @"test", @"enabled": @false, @"buttonColor": inputColor, @"buttonFontSize": @22, @"buttonFontWeight": @"800"}]; self.uut = [[RNNRootViewController alloc] initWithLayoutInfo:nil rootViewCreator:nil eventEmitter:nil presenter:[RNNViewControllerPresenter new] options:self.options defaultOptions:nil]; - RNNNavigationController* nav = [[RNNNavigationController alloc] initWithLayoutInfo:nil creator:_creator childViewControllers:@[self.uut] options:nil defaultOptions:nil presenter:nil]; + RNNNavigationController* nav = [[RNNNavigationController alloc] initWithLayoutInfo:nil creator:_creator options:nil defaultOptions:nil presenter:nil eventEmitter:nil]; + [nav setViewControllers:@[self.uut]]; RNNUIBarButtonItem* button = (RNNUIBarButtonItem*)[nav.topViewController.navigationItem.rightBarButtonItems objectAtIndex:0]; NSString* expectedButtonId = @"testId"; @@ -446,8 +448,9 @@ -(void)testRightButtonsWithTitle_withStyle { -(void)testLeftButtonsWithTitle_withoutStyle { self.options.topBar.leftButtons = @[@{@"id": @"testId", @"text": @"test"}]; self.uut = [[RNNRootViewController alloc] initWithLayoutInfo:nil rootViewCreator:nil eventEmitter:nil presenter:[RNNViewControllerPresenter new] options:self.options defaultOptions:nil]; - RNNNavigationController* nav = [[RNNNavigationController alloc] initWithLayoutInfo:nil creator:_creator childViewControllers:@[self.uut] options:nil defaultOptions:nil presenter:nil]; - + RNNNavigationController* nav = [[RNNNavigationController alloc] initWithLayoutInfo:nil creator:_creator options:nil defaultOptions:nil presenter:nil eventEmitter:nil]; + [nav setViewControllers:@[self.uut]]; + RNNUIBarButtonItem* button = (RNNUIBarButtonItem*)[nav.topViewController.navigationItem.leftBarButtonItems objectAtIndex:0]; NSString* expectedButtonId = @"testId"; NSString* expectedTitle = @"test"; @@ -461,7 +464,8 @@ -(void)testLeftButtonsWithTitle_withStyle { self.options.topBar.leftButtons = @[@{@"id": @"testId", @"text": @"test", @"enabled": @false, @"buttonColor": inputColor, @"buttonFontSize": @22, @"buttonFontWeight": @"800"}]; self.uut = [[RNNRootViewController alloc] initWithLayoutInfo:nil rootViewCreator:nil eventEmitter:nil presenter:[RNNViewControllerPresenter new] options:self.options defaultOptions:nil]; - RNNNavigationController* nav = [[RNNNavigationController alloc] initWithLayoutInfo:nil creator:_creator childViewControllers:@[self.uut] options:nil defaultOptions:nil presenter:nil]; + RNNNavigationController* nav = [[RNNNavigationController alloc] initWithLayoutInfo:nil creator:_creator options:nil defaultOptions:nil presenter:nil eventEmitter:nil]; + [nav setViewControllers:@[self.uut]]; RNNUIBarButtonItem* button = (RNNUIBarButtonItem*)[nav.topViewController.navigationItem.leftBarButtonItems objectAtIndex:0]; NSString* expectedButtonId = @"testId"; @@ -565,7 +569,8 @@ - (void)testOverrideOptions { - (RNNNavigationController *)createNavigationController { - RNNNavigationController* nav = [[RNNNavigationController alloc] initWithLayoutInfo:nil creator:nil childViewControllers:@[self.uut] options:[[RNNNavigationOptions alloc] initEmptyOptions] defaultOptions:nil presenter:[[RNNNavigationControllerPresenter alloc] init]]; + RNNNavigationController* nav = [[RNNNavigationController alloc] initWithLayoutInfo:nil creator:nil options:[[RNNNavigationOptions alloc] initEmptyOptions] defaultOptions:nil presenter:[[RNNNavigationControllerPresenter alloc] init] eventEmitter:nil]; + [nav setViewControllers:@[self.uut]]; return nav; } diff --git a/lib/ios/ReactNativeNavigationTests/RNNSideMenuControllerTest.m b/lib/ios/ReactNativeNavigationTests/RNNSideMenuControllerTest.m index 0eb1a4072a4..946a551492a 100644 --- a/lib/ios/ReactNativeNavigationTests/RNNSideMenuControllerTest.m +++ b/lib/ios/ReactNativeNavigationTests/RNNSideMenuControllerTest.m @@ -16,7 +16,7 @@ - (void)setUp { _leftVC = [[RNNSideMenuChildVC alloc] initWithLayoutInfo:nil childViewControllers:@[[RNNRootViewController new]] options:nil defaultOptions:nil presenter:nil type:RNNSideMenuChildTypeLeft]; _rightVC = [[RNNSideMenuChildVC alloc] initWithLayoutInfo:nil childViewControllers:@[[RNNRootViewController new]] options:nil defaultOptions:nil presenter:nil type:RNNSideMenuChildTypeRight]; _centerVC = [[RNNSideMenuChildVC alloc] initWithLayoutInfo:nil childViewControllers:@[[RNNRootViewController new]] options:nil defaultOptions:nil presenter:nil type:RNNSideMenuChildTypeCenter]; - self.uut = [[RNNSideMenuController alloc] initWithLayoutInfo:nil childViewControllers:@[_leftVC, _centerVC, _rightVC] options:[[RNNNavigationOptions alloc] initEmptyOptions] defaultOptions:nil presenter:nil]; + self.uut = [[RNNSideMenuController alloc] initWithLayoutInfo:nil creator:nil childViewControllers:@[_leftVC, _centerVC, _rightVC] options:[[RNNNavigationOptions alloc] initEmptyOptions] defaultOptions:nil presenter:nil eventEmitter:nil]; } - (void)testSetSideMenuWidthShouldUpdateLeftReactViewFrameWidth { diff --git a/lib/ios/ReactNativeNavigationTests/RNNStoreTest.m b/lib/ios/ReactNativeNavigationTests/RNNStoreTest.m index cb0380020fd..66690f4da4e 100644 --- a/lib/ios/ReactNativeNavigationTests/RNNStoreTest.m +++ b/lib/ios/ReactNativeNavigationTests/RNNStoreTest.m @@ -77,17 +77,6 @@ - (void)testPopWillRemoveVcFromStore { XCTAssertNil([self.store findComponentForId:vcId]); } - -- (void)testRemoveComponentByInstance { - NSString *componentId1 = @"cntId1"; - UIViewController *vc1 = [UIViewController new]; - - [self.store setComponent:vc1 componentId:componentId1]; - [self.store removeComponentByViewControllerInstance:vc1]; - - XCTAssertNil([self.store findComponentForId:@"cntId1"]); -} - - (void)testRemoveAllComponentsFromWindowShouldRemoveComponentsInWindow { UIViewController* overlayVC = [self createMockedViewControllerWithWindow:[UIWindow new]]; diff --git a/lib/ios/ReactNativeNavigationTests/RNNTabBarControllerTest.m b/lib/ios/ReactNativeNavigationTests/RNNTabBarControllerTest.m index ab803a6ffd7..07cc270824b 100644 --- a/lib/ios/ReactNativeNavigationTests/RNNTabBarControllerTest.m +++ b/lib/ios/ReactNativeNavigationTests/RNNTabBarControllerTest.m @@ -26,7 +26,8 @@ - (void)setUp { self.mockTabBarPresenter = [OCMockObject partialMockForObject:[[RNNTabBarPresenter alloc] init]]; self.mockChildViewController = [OCMockObject partialMockForObject:[RNNRootViewController new]]; self.mockEventEmmiter = [OCMockObject partialMockForObject:[RNNEventEmitter new]]; - self.mockUut = [OCMockObject partialMockForObject:[[RNNTabBarController alloc] initWithLayoutInfo:nil childViewControllers:@[[[UIViewController alloc] init]] options:[[RNNNavigationOptions alloc] initWithDict:@{}] defaultOptions:nil presenter:self.mockTabBarPresenter eventEmitter:self.mockEventEmmiter]]; + self.mockUut = [OCMockObject partialMockForObject:[[RNNTabBarController alloc] initWithLayoutInfo:nil creator:nil options:[[RNNNavigationOptions alloc] initWithDict:@{}] defaultOptions:nil presenter:self.mockTabBarPresenter eventEmitter:self.mockEventEmmiter]]; + [self.mockUut setViewControllers:@[[[UIViewController alloc] init]]]; OCMStub([self.mockUut selectedViewController]).andReturn(self.mockChildViewController); } @@ -38,7 +39,8 @@ - (void)testInitWithLayoutInfo_shouldSetMultipleViewControllers { UIViewController* vc1 = [[UIViewController alloc] init]; UIViewController* vc2 = [[UIViewController alloc] init]; - RNNTabBarController* uut = [[RNNTabBarController alloc] initWithLayoutInfo:nil childViewControllers:@[vc1, vc2] options:[[RNNNavigationOptions alloc] initWithDict:@{}] defaultOptions:nil presenter:[[RNNViewControllerPresenter alloc] init]]; + RNNTabBarController* uut = [[RNNTabBarController alloc] initWithLayoutInfo:nil creator:nil options:[[RNNNavigationOptions alloc] initWithDict:@{}] defaultOptions:nil presenter:[[RNNViewControllerPresenter alloc] init] eventEmitter:nil]; + [uut setViewControllers:@[vc1, vc2]]; XCTAssertTrue(uut.viewControllers.count == 2); } @@ -48,7 +50,8 @@ - (void)testInitWithLayoutInfo_shouldInitializeDependencies { RNNTabBarPresenter* presenter = [[RNNTabBarPresenter alloc] init]; NSArray* childViewControllers = @[[UIViewController new]]; - RNNTabBarController* uut = [[RNNTabBarController alloc] initWithLayoutInfo:layoutInfo childViewControllers:childViewControllers options:options defaultOptions:nil presenter:presenter]; + RNNTabBarController* uut = [[RNNTabBarController alloc] initWithLayoutInfo:layoutInfo creator:nil options:options defaultOptions:nil presenter:presenter eventEmitter:nil]; + [uut setViewControllers:childViewControllers]; XCTAssertTrue(uut.layoutInfo == layoutInfo); XCTAssertTrue(uut.options == options); XCTAssertTrue(uut.presenter == presenter); @@ -63,7 +66,8 @@ - (void)testInitWithEventEmmiter_shouldInitializeDependencies { NSArray* childViewControllers = @[[UIViewController new]]; - RNNTabBarController* uut = [[RNNTabBarController alloc] initWithLayoutInfo:layoutInfo childViewControllers:childViewControllers options:options defaultOptions:nil presenter:presenter eventEmitter:eventEmmiter]; + RNNTabBarController* uut = [[RNNTabBarController alloc] initWithLayoutInfo:layoutInfo creator:nil options:options defaultOptions:nil presenter:presenter eventEmitter:eventEmmiter]; + [uut setViewControllers:childViewControllers]; XCTAssertTrue(uut.layoutInfo == layoutInfo); XCTAssertTrue(uut.options == options); XCTAssertTrue(uut.presenter == presenter); @@ -72,7 +76,7 @@ - (void)testInitWithEventEmmiter_shouldInitializeDependencies { } - (void)testInitWithLayoutInfo_shouldSetDelegate { - RNNTabBarController* uut = [[RNNTabBarController alloc] initWithLayoutInfo:nil childViewControllers:nil options:[[RNNNavigationOptions alloc] initWithDict:@{}] defaultOptions:nil presenter:[[RNNViewControllerPresenter alloc] init]]; + RNNTabBarController* uut = [[RNNTabBarController alloc] initWithLayoutInfo:nil creator:nil options:[[RNNNavigationOptions alloc] initWithDict:@{}] defaultOptions:nil presenter:[[RNNBasePresenter alloc] init] eventEmitter:nil]; XCTAssertTrue(uut.delegate == uut); } @@ -148,7 +152,8 @@ - (void)testSetSelectedIndexByComponentID_ShouldSetSelectedIndexWithCorrectIndex RNNRootViewController* vc = [[RNNRootViewController alloc] initWithLayoutInfo:layoutInfo rootViewCreator:nil eventEmitter:nil presenter:nil options:nil defaultOptions:nil]; - RNNTabBarController* uut = [[RNNTabBarController alloc] initWithLayoutInfo:nil childViewControllers:@[[UIViewController new], vc] options:nil defaultOptions:nil presenter:[RNNTabBarPresenter new]]; + RNNTabBarController* uut = [[RNNTabBarController alloc] initWithLayoutInfo:nil creator:nil options:nil defaultOptions:nil presenter:[RNNTabBarPresenter new] eventEmitter:nil]; + [uut setViewControllers:@[[UIViewController new], vc]]; [uut setSelectedIndexByComponentID:@"componentId"]; XCTAssertTrue(uut.selectedIndex == 1); } diff --git a/lib/ios/ReactNativeNavigationTests/UIViewController+LayoutProtocolTest.m b/lib/ios/ReactNativeNavigationTests/UIViewController+LayoutProtocolTest.m new file mode 100644 index 00000000000..6381fc49945 --- /dev/null +++ b/lib/ios/ReactNativeNavigationTests/UIViewController+LayoutProtocolTest.m @@ -0,0 +1,35 @@ +#import +#import +#import "UIViewController+LayoutProtocol.h" + +@interface UIViewController_LayoutProtocolTest : XCTestCase + +@property (nonatomic, retain) UIViewController* uut; + +@end + +@implementation UIViewController_LayoutProtocolTest + +- (void)setUp { + [super setUp]; + self.uut = [OCMockObject partialMockForObject:[UIViewController new]]; + self.uut.layoutInfo = [[RNNLayoutInfo alloc] init]; + self.uut.layoutInfo.componentId = @"componentId"; +} + +- (void)testSetStoreShouldSaveComponent { + RNNStore* store = [[RNNStore alloc] init]; + [self.uut setStore:store]; + XCTAssertNotNil([store findComponentForId:self.uut.layoutInfo.componentId]); +} + +- (void)testDeallocShouldRemoveComponentFromStore { + RNNStore* store = [[RNNStore alloc] init]; + [self.uut setStore:store]; + XCTAssertNotNil([store findComponentForId:self.uut.layoutInfo.componentId]); + self.uut = nil; + XCTAssertNil([store findComponentForId:self.uut.layoutInfo.componentId]); +} + + +@end diff --git a/lib/ios/UIViewController+LayoutProtocol.h b/lib/ios/UIViewController+LayoutProtocol.h new file mode 100644 index 00000000000..b51990b742c --- /dev/null +++ b/lib/ios/UIViewController+LayoutProtocol.h @@ -0,0 +1,30 @@ +#import +#import "RNNEventEmitter.h" +#import "RNNLayoutProtocol.h" +#import "RNNStore.h" + +typedef void (^RNNReactViewReadyCompletionBlock)(void); + +@interface UIViewController (LayoutProtocol) + +- (void)renderTreeAndWait:(BOOL)wait perform:(RNNReactViewReadyCompletionBlock)readyBlock; + +- (UIViewController *)getCurrentChild; + +- (void)mergeOptions:(RNNNavigationOptions *)options; + +- (RNNNavigationOptions *)resolveOptions; + +- (void)setDefaultOptions:(RNNNavigationOptions *)defaultOptions; + +- (void)overrideOptions:(RNNNavigationOptions *)options; + +@property (nonatomic, retain) RNNBasePresenter* presenter; +@property (nonatomic, retain) RNNLayoutInfo* layoutInfo; +@property (nonatomic, strong) RNNNavigationOptions* options; +@property (nonatomic, strong) RNNNavigationOptions* defaultOptions; +@property (nonatomic, strong) RNNEventEmitter* eventEmitter; +@property (nonatomic, strong) RNNStore* store; +@property (nonatomic) id creator; + +@end diff --git a/lib/ios/UIViewController+LayoutProtocol.m b/lib/ios/UIViewController+LayoutProtocol.m new file mode 100644 index 00000000000..956e5e2dae2 --- /dev/null +++ b/lib/ios/UIViewController+LayoutProtocol.m @@ -0,0 +1,145 @@ + +#import "UIViewController+LayoutProtocol.h" +#import + +@implementation UIViewController (LayoutProtocol) + +- (instancetype)initWithLayoutInfo:(RNNLayoutInfo *)layoutInfo + creator:(id)creator + options:(RNNNavigationOptions *)options + defaultOptions:(RNNNavigationOptions *)defaultOptions + presenter:(RNNBasePresenter *)presenter + eventEmitter:(RNNEventEmitter *)eventEmitter { + self = [self init]; + + self.options = options; + self.defaultOptions = defaultOptions; + self.layoutInfo = layoutInfo; + self.creator = creator; + self.eventEmitter = eventEmitter; + self.presenter = presenter; + [self.presenter bindViewController:self]; + [self.presenter applyOptionsOnInit:self.options]; + + return self; +} + +- (void)setStore:(RNNStore *)store { + objc_setAssociatedObject(self, @selector(store), store, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + [self.store setComponent:self componentId:self.layoutInfo.componentId]; +} + +- (RNNNavigationOptions *)resolveOptions { + return [(RNNNavigationOptions *)[self.options mergeInOptions:self.getCurrentChild.resolveOptions.copy] withDefault:self.defaultOptions]; +} + +- (void)mergeOptions:(RNNNavigationOptions *)options { + [self.presenter mergeOptions:options currentOptions:self.options defaultOptions:self.defaultOptions]; + [((UIViewController *)self.parentViewController) mergeOptions:options]; +} + +- (void)overrideOptions:(RNNNavigationOptions *)options { + [self.options overrideOptions:options]; +} + +- (void)renderTreeAndWait:(BOOL)wait perform:(RNNReactViewReadyCompletionBlock)readyBlock { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ + dispatch_group_t group = dispatch_group_create(); + for (UIViewController* childViewController in self.childViewControllers) { + dispatch_group_enter(group); + dispatch_async(dispatch_get_main_queue(), ^{ + [childViewController renderTreeAndWait:wait perform:^{ + dispatch_group_leave(group); + }]; + }); + } + + dispatch_group_enter(group); + [self.presenter renderComponents:self.resolveOptions perform:^{ + dispatch_group_leave(group); + }]; + dispatch_group_wait(group, DISPATCH_TIME_FOREVER); + + dispatch_async(dispatch_get_main_queue(), ^{ + readyBlock(); + }); + }); +} + +- (UIViewController *)getCurrentChild { + return nil; +} + +- (void)onChildWillAppear { + [self.presenter applyOptions:self.resolveOptions]; + [((UISplitViewController *)self.parentViewController) onChildWillAppear]; +} + +- (void)willMoveToParentViewController:(UIViewController *)parent { + if (parent) { + [self.presenter applyOptionsOnWillMoveToParentViewController:self.resolveOptions]; + } +} + +- (void)dealloc { + [self.store removeComponent:self.layoutInfo.componentId]; +} + + +#pragma mark getters and setters to associated object + +- (RNNNavigationOptions *)options { + return objc_getAssociatedObject(self, @selector(options)); +} + +- (void)setOptions:(RNNNavigationOptions *)options { + objc_setAssociatedObject(self, @selector(options), options, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +- (RNNNavigationOptions *)defaultOptions { + return objc_getAssociatedObject(self, @selector(defaultOptions)); +} + +- (void)setDefaultOptions:(RNNNavigationOptions *)defaultOptions { + objc_setAssociatedObject(self, @selector(defaultOptions), defaultOptions, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +- (RNNLayoutInfo *)layoutInfo { + return objc_getAssociatedObject(self, @selector(layoutInfo)); +} + +- (void)setLayoutInfo:(RNNLayoutInfo *)layoutInfo { + objc_setAssociatedObject(self, @selector(layoutInfo), layoutInfo, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +- (RNNBasePresenter *)presenter { + return objc_getAssociatedObject(self, @selector(presenter)); +} + +- (void)setPresenter:(RNNBasePresenter *)presenter { + objc_setAssociatedObject(self, @selector(presenter), presenter, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +- (RNNEventEmitter *)eventEmitter { + return objc_getAssociatedObject(self, @selector(eventEmitter)); +} + +- (void)setEventEmitter:(RNNEventEmitter *)eventEmitter { + objc_setAssociatedObject(self, @selector(eventEmitter), eventEmitter, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +- (RNNStore *)store { + return objc_getAssociatedObject(self, @selector(store)); +} + +- (id)creator { + return objc_getAssociatedObject(self, @selector(creator)); +} + +- (void)setCreator:(id)creator { + objc_setAssociatedObject(self, @selector(creator), creator, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + + + +@end diff --git a/playground/src/screens/OverlayAlert.js b/playground/src/screens/OverlayAlert.js index 661e4be547a..dd8bfd8fb76 100644 --- a/playground/src/screens/OverlayAlert.js +++ b/playground/src/screens/OverlayAlert.js @@ -2,6 +2,8 @@ const React = require('react'); const { Text, Button, View, Alert, Platform } = require('react-native'); const { Navigation } = require('react-native-navigation'); +const { component } = require('../commons/Layouts'); +const Screens = require('./Screens'); const { OVERLAY_ALERT_HEADER, @@ -23,13 +25,8 @@ class OverlayAlert extends React.PureComponent { } dismiss = () => Navigation.dismissOverlay(this.props.componentId); - setRoot = () => Navigation.setRoot({ - root: { - component: { - name: 'navigation.playground.TextScreen' - } - } - }); + setRoot = () => Navigation.setRoot({ root: component(Screens.Pushed) }); + setInterceptTouch = () => Navigation.mergeOptions(this.props.componentId, { overlay: { interceptTouchOutside: false