react-native-navigation的迁移库

RNNModalManager.m 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. #import "RNNModalManager.h"
  2. #import "RNNRootViewController.h"
  3. @implementation RNNModalManager {
  4. RNNTransitionWithComponentIdCompletionBlock _completionBlock;
  5. NSMutableArray* _pendingModalIdsToDismiss;
  6. NSMutableArray* _presentedModals;
  7. }
  8. -(instancetype)init {
  9. self = [super init];
  10. _pendingModalIdsToDismiss = [[NSMutableArray alloc] init];
  11. _presentedModals = [[NSMutableArray alloc] init];
  12. return self;
  13. }
  14. -(void)showModal:(BOOL)animated {
  15. UIViewController* topVC = [self topPresentedVC];
  16. topVC.definesPresentationContext = YES;
  17. if ([topVC conformsToProtocol:@protocol(RNNRootViewProtocol)]) {
  18. UIViewController<RNNRootViewProtocol> *navigationTopVC = (UIViewController<RNNRootViewProtocol>*)topVC;
  19. RNNNavigationOptions* options = navigationTopVC.getLeafViewController.options;
  20. if (options.animations.showModal.hasCustomAnimation) {
  21. self.toVC.transitioningDelegate = navigationTopVC;
  22. }
  23. }
  24. [topVC presentViewController:self.toVC animated:animated completion:^{
  25. if (_completionBlock) {
  26. _completionBlock(self.toVC.getLeafViewController.componentId);
  27. _completionBlock = nil;
  28. }
  29. [_presentedModals addObject:self.toVC.navigationController ? self.toVC.navigationController : self.toVC];
  30. self.toVC = nil;
  31. }];
  32. }
  33. -(void)showModal:(UIViewController *)viewController animated:(BOOL)animated completion:(RNNTransitionWithComponentIdCompletionBlock)completion {
  34. self.toVC = (UIViewController<RNNRootViewProtocol>*)viewController;
  35. RNNNavigationOptions* options = self.toVC.getLeafViewController.options;
  36. _completionBlock = completion;
  37. if ([self.toVC respondsToSelector:@selector(applyModalOptions)]) {
  38. [self.toVC.getLeafViewController applyModalOptions];
  39. }
  40. if ([self.toVC respondsToSelector:@selector(isCustomViewController)] &&
  41. [self.toVC.getLeafViewController isCustomViewController]
  42. ) {
  43. [self showModal:animated];
  44. } else {
  45. [self.toVC.getLeafViewController waitForReactViewRender:options.animations.showModal.waitForRender perform:^{
  46. [self showModal:animated];
  47. }];
  48. }
  49. }
  50. - (void)dismissModal:(UIViewController *)viewController completion:(RNNTransitionCompletionBlock)completion {
  51. if (viewController) {
  52. [_pendingModalIdsToDismiss addObject:viewController];
  53. [self removePendingNextModalIfOnTop:completion];
  54. }
  55. }
  56. -(void)dismissAllModalsAnimated:(BOOL)animated {
  57. UIViewController *root = UIApplication.sharedApplication.delegate.window.rootViewController;
  58. [root dismissViewControllerAnimated:animated completion:nil];
  59. [_delegate dismissedMultipleModals:_presentedModals];
  60. [_pendingModalIdsToDismiss removeAllObjects];
  61. [_presentedModals removeAllObjects];
  62. }
  63. #pragma mark - private
  64. -(void)removePendingNextModalIfOnTop:(RNNTransitionCompletionBlock)completion {
  65. UIViewController<RNNRootViewProtocol> *modalToDismiss = [_pendingModalIdsToDismiss lastObject];
  66. RNNNavigationOptions* options = modalToDismiss.getLeafViewController.options;
  67. if(!modalToDismiss) {
  68. return;
  69. }
  70. UIViewController* topPresentedVC = [self topPresentedVC];
  71. if ([options.animations.showModal hasCustomAnimation]) {
  72. modalToDismiss.transitioningDelegate = modalToDismiss;
  73. }
  74. if (modalToDismiss == topPresentedVC || [[topPresentedVC childViewControllers] containsObject:modalToDismiss]) {
  75. [modalToDismiss dismissViewControllerAnimated:options.animations.dismissModal.enable completion:^{
  76. [_pendingModalIdsToDismiss removeObject:modalToDismiss];
  77. if (modalToDismiss.view) {
  78. [self dismissedModal:modalToDismiss];
  79. }
  80. if (completion) {
  81. completion();
  82. }
  83. [self removePendingNextModalIfOnTop:nil];
  84. }];
  85. } else {
  86. [modalToDismiss.view removeFromSuperview];
  87. modalToDismiss.view = nil;
  88. modalToDismiss.getLeafViewController.options.animations.dismissModal.enable = NO;
  89. [self dismissedModal:modalToDismiss];
  90. if (completion) {
  91. completion();
  92. }
  93. }
  94. }
  95. - (void)dismissedModal:(UIViewController *)viewController {
  96. [_presentedModals removeObject:viewController.navigationController ? viewController.navigationController : viewController];
  97. [_delegate dismissedModal:viewController];
  98. }
  99. -(UIViewController*)topPresentedVC {
  100. UIViewController *root = UIApplication.sharedApplication.delegate.window.rootViewController;
  101. while(root.presentedViewController) {
  102. root = root.presentedViewController;
  103. }
  104. return root;
  105. }
  106. -(UIViewController*)topPresentedVCLeaf {
  107. id root = [self topPresentedVC];
  108. return [root topViewController] ? [root topViewController] : root;
  109. }
  110. @end