react-native-navigation的迁移库

RNNNavigationStackManager.m 5.1KB

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