react-native-navigation的迁移库

RNNStackPresenter.m 8.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. #import "RNNStackPresenter.h"
  2. #import "UINavigationController+RNNOptions.h"
  3. #import "RNNStackController.h"
  4. #import "RNNCustomTitleView.h"
  5. #import "TopBarPresenterCreator.h"
  6. @interface RNNStackPresenter() {
  7. RNNReactComponentRegistry* _componentRegistry;
  8. UIView* _customTopBar;
  9. UIView* _customTopBarBackground;
  10. RNNReactView* _customTopBarBackgroundReactView;
  11. TopBarPresenter* _topBarPresenter;
  12. }
  13. @property (nonatomic, weak) RNNStackController* stackController;
  14. @end
  15. @implementation RNNStackPresenter
  16. - (instancetype)initWithComponentRegistry:(RNNReactComponentRegistry *)componentRegistry defaultOptions:(RNNNavigationOptions *)defaultOptions {
  17. self = [super initWithDefaultOptions:defaultOptions];
  18. _componentRegistry = componentRegistry;
  19. return self;
  20. }
  21. - (void)bindViewController:(UIViewController *)boundViewController {
  22. [super bindViewController:boundViewController];
  23. _topBarPresenter = [TopBarPresenterCreator createWithBoundedNavigationController:self.stackController];
  24. }
  25. - (RNNStackController *)stackController {
  26. return (RNNStackController *)self.boundViewController;
  27. }
  28. - (void)applyOptions:(RNNNavigationOptions *)options {
  29. [super applyOptions:options];
  30. RNNStackController* stack = self.stackController;
  31. RNNNavigationOptions * withDefault = [options withDefault:[self defaultOptions]];
  32. self.interactivePopGestureDelegate = [InteractivePopGestureDelegate new];
  33. self.interactivePopGestureDelegate.navigationController = stack;
  34. self.interactivePopGestureDelegate.originalDelegate = stack.interactivePopGestureRecognizer.delegate;
  35. stack.interactivePopGestureRecognizer.delegate = self.interactivePopGestureDelegate;
  36. [stack setBarStyle:[RCTConvert UIBarStyle:[withDefault.topBar.barStyle getWithDefaultValue:@"default"]]];
  37. [stack setInteractivePopGestureEnabled:[withDefault.popGesture getWithDefaultValue:YES]];
  38. [stack setRootBackgroundImage:[withDefault.rootBackgroundImage getWithDefaultValue:nil]];
  39. [stack setNavigationBarTestId:[withDefault.topBar.testID getWithDefaultValue:nil]];
  40. [stack setNavigationBarVisible:[withDefault.topBar.visible getWithDefaultValue:YES] animated:[withDefault.topBar.animate getWithDefaultValue:YES]];
  41. [stack hideBarsOnScroll:[withDefault.topBar.hideOnScroll getWithDefaultValue:NO]];
  42. [_topBarPresenter applyOptions:withDefault.topBar];
  43. [stack setNavigationBarBlur:[withDefault.topBar.background.blur getWithDefaultValue:NO]];
  44. [stack setNavigationBarLargeTitleVisible:[withDefault.topBar.largeTitle.visible getWithDefaultValue:NO]];
  45. [stack setNavigationBarClipsToBounds:[withDefault.topBar.background.clipToBounds getWithDefaultValue:NO]];
  46. [stack setBackButtonColor:[withDefault.topBar.backButton.color getWithDefaultValue:nil]];
  47. }
  48. - (void)applyOptionsOnViewDidLayoutSubviews:(RNNNavigationOptions *)options {
  49. RNNNavigationOptions *withDefault = [options withDefault:[self defaultOptions]];
  50. if (withDefault.topBar.background.component.name.hasValue) {
  51. [self presentBackgroundComponent];
  52. }
  53. }
  54. - (void)applyOptionsBeforePopping:(RNNNavigationOptions *)options {
  55. RNNNavigationOptions *withDefault = [options withDefault:[self defaultOptions]];
  56. RNNStackController* navigationController = self.stackController;
  57. [navigationController setNavigationBarLargeTitleVisible:[withDefault.topBar.largeTitle.visible getWithDefaultValue:NO]];
  58. [_topBarPresenter applyOptionsBeforePopping:options.topBar];
  59. }
  60. - (void)mergeOptions:(RNNNavigationOptions *)options resolvedOptions:(RNNNavigationOptions *)resolvedOptions {
  61. [super mergeOptions:options resolvedOptions:resolvedOptions];
  62. RNNStackController* stack = self.stackController;
  63. if (options.popGesture.hasValue) {
  64. [stack setInteractivePopGestureEnabled:options.popGesture.get];
  65. }
  66. if (options.rootBackgroundImage.hasValue) {
  67. [stack setRootBackgroundImage:options.rootBackgroundImage.get];
  68. }
  69. if (options.topBar.testID.hasValue) {
  70. [stack setNavigationBarTestId:options.topBar.testID.get];
  71. }
  72. if (options.topBar.visible.hasValue) {
  73. [stack setNavigationBarVisible:options.topBar.visible.get animated:[options.topBar.animate getWithDefaultValue:YES]];
  74. }
  75. if (options.topBar.hideOnScroll.hasValue) {
  76. [stack hideBarsOnScroll:[options.topBar.hideOnScroll get]];
  77. }
  78. if (options.topBar.barStyle.hasValue) {
  79. [stack setBarStyle:[RCTConvert UIBarStyle:options.topBar.barStyle.get]];
  80. }
  81. if (options.topBar.background.clipToBounds.hasValue) {
  82. [stack setNavigationBarClipsToBounds:[options.topBar.background.clipToBounds get]];
  83. }
  84. if (options.topBar.background.blur.hasValue) {
  85. [stack setNavigationBarBlur:[options.topBar.background.blur get]];
  86. }
  87. if (options.topBar.largeTitle.visible.hasValue) {
  88. [stack setNavigationBarLargeTitleVisible:options.topBar.largeTitle.visible.get];
  89. }
  90. if (options.topBar.backButton.color.hasValue) {
  91. [stack setBackButtonColor:options.topBar.backButton.color.get];
  92. }
  93. if (options.topBar.component.name.hasValue) {
  94. [self setCustomNavigationBarView:options perform:nil];
  95. }
  96. if (options.topBar.background.component.name.hasValue) {
  97. [self setCustomNavigationComponentBackground:options perform:nil];
  98. }
  99. RNNNavigationOptions * withDefault = (RNNNavigationOptions *) [[options mergeInOptions:resolvedOptions] withDefault:[self defaultOptions]];
  100. [_topBarPresenter mergeOptions:options.topBar defaultOptions:withDefault.topBar];
  101. }
  102. - (void)renderComponents:(RNNNavigationOptions *)options perform:(RNNReactViewReadyCompletionBlock)readyBlock {
  103. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
  104. dispatch_group_t group = dispatch_group_create();
  105. dispatch_group_enter(group);
  106. dispatch_async(dispatch_get_main_queue(), ^{
  107. [self setCustomNavigationBarView:options perform:^{
  108. dispatch_group_leave(group);
  109. }];
  110. });
  111. dispatch_group_enter(group);
  112. dispatch_async(dispatch_get_main_queue(), ^{
  113. [self setCustomNavigationComponentBackground:options perform:^{
  114. dispatch_group_leave(group);
  115. }];
  116. });
  117. dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
  118. dispatch_async(dispatch_get_main_queue(), ^{
  119. if (readyBlock) {
  120. readyBlock();
  121. }
  122. });
  123. });
  124. }
  125. - (void)setCustomNavigationBarView:(RNNNavigationOptions *)options perform:(RNNReactViewReadyCompletionBlock)readyBlock {
  126. RNNStackController* stack = self.stackController;
  127. if (![options.topBar.component.waitForRender getWithDefaultValue:NO] && readyBlock) {
  128. readyBlock();
  129. readyBlock = nil;
  130. }
  131. if (options.topBar.component.name.hasValue) {
  132. NSString* currentChildComponentId = [stack getCurrentChild].layoutInfo.componentId;
  133. RCTRootView *reactView = [_componentRegistry createComponentIfNotExists:options.topBar.component parentComponentId:currentChildComponentId reactViewReadyBlock:readyBlock];
  134. if (_customTopBar) {
  135. [_customTopBar removeFromSuperview];
  136. }
  137. _customTopBar = [[RNNCustomTitleView alloc] initWithFrame:stack.navigationBar.bounds subView:reactView alignment:@"fill"];
  138. reactView.backgroundColor = UIColor.clearColor;
  139. _customTopBar.backgroundColor = UIColor.clearColor;
  140. [stack.navigationBar addSubview:_customTopBar];
  141. } else {
  142. [_customTopBar removeFromSuperview];
  143. _customTopBar = nil;
  144. if (readyBlock) {
  145. readyBlock();
  146. }
  147. }
  148. }
  149. - (void)setCustomNavigationComponentBackground:(RNNNavigationOptions *)options perform:(RNNReactViewReadyCompletionBlock)readyBlock {
  150. RNNNavigationOptions *withDefault = [options withDefault:[self defaultOptions]];
  151. RNNStackController* stack = self.stackController;
  152. if (![withDefault.topBar.background.component.waitForRender getWithDefaultValue:NO] && readyBlock) {
  153. readyBlock();
  154. readyBlock = nil;
  155. }
  156. if (withDefault.topBar.background.component.name.hasValue) {
  157. NSString* currentChildComponentId = [stack getCurrentChild].layoutInfo.componentId;
  158. RNNReactView *reactView = [_componentRegistry createComponentIfNotExists:withDefault.topBar.background.component parentComponentId:currentChildComponentId reactViewReadyBlock:readyBlock];
  159. _customTopBarBackgroundReactView = reactView;
  160. } else {
  161. [_customTopBarBackground removeFromSuperview];
  162. _customTopBarBackground = nil;
  163. if (readyBlock) {
  164. readyBlock();
  165. }
  166. }
  167. }
  168. - (void)presentBackgroundComponent {
  169. RNNStackController* stack = self.stackController;
  170. if (_customTopBarBackground) {
  171. [_customTopBarBackground removeFromSuperview];
  172. }
  173. RNNCustomTitleView* customTopBarBackground = [[RNNCustomTitleView alloc] initWithFrame:stack.navigationBar.bounds subView:_customTopBarBackgroundReactView alignment:@"fill"];
  174. _customTopBarBackground = customTopBarBackground;
  175. [stack.navigationBar insertSubview:_customTopBarBackground atIndex:1];
  176. }
  177. - (void)dealloc {
  178. [_componentRegistry removeComponent:self.boundComponentId];
  179. }
  180. @end