[React Native] 在 iOS 中,关于 ViewController 的二三事

  • 获得当前 Component 所属 ViewController 的办法(这是后续各个操作的基础)
    1. 创建或找到一个现成的 BridgeModule 类
    2. 在该 BridgeModule 类的 .m 文件中,确保包含
     #import "UIView+React.h"
    
    1. 在 @implementation 中,确保包含
     @synthesize bridge = _bridge;
    
    1. 在 @implementation 中,RCT_EXPORT_METHOD 一个 Bridge 方法
     RCT_EXPORT_METHOD(
       sometingToDoWithTheViewControllerOfTheComponent:(nonnull NSNumber *)reactTag // Component 对象的 reactTag
       resolver:(RCTPromiseResolveBlock)resolve // 这行 
       rejecter:(RCTPromiseRejectBlock)reject   // 和这行是可选的,如果需要在执行完毕后给 JavaScript 通知的话,就带上
     )
     {
       // 实现后文详述
     }
    
    1. 在 Bridge 方法中,通过如下代码取得 reactTag 对应的 view,并基于该 view 取得它所对应的 viewController
     RCTUIManager *uiManager = _bridge.uiManager;
     dispatch_async(uiManager.methodQueue, ^{
       [uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *,UIView *> *viewRegistry) {
         UIView *view = viewRegistry[reactTag];
         UIViewController *viewController = (UIViewController *)view.reactViewController;
         // It's now ok to do something with the viewController
         // which is in charge of the component.
       }
     }
    
  • 导航到其它 ViewController 的办法
    1. 基于上述办法取到当前 Component 所属的 ViewController
    2. 通过如下代码取得它所属的 navigationController,调用它的 pushViewController 或 presentViewController 方法即可
     [viewController.navigationController pushViewController:anotherViewController animated:YES]; // 跳转
     [viewController.navigationController presentViewController:anotherViewController animated:YES completion:^{}] ;// 弹出
    
    1. 完整代码如下:
     RCT_EXPORT_METHOD
     (
      pushViewControllerXYZ:(nonnull NSNumber *)reactTag
      resolver:(RCTPromiseResolveBlock)resolve
      rejecter:(RCTPromiseRejectBlock)reject
     )
     {
       RCTUIManager *uiManager = _bridge.uiManager;
       dispatch_async(uiManager.methodQueue, ^{
         [uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *,UIView *> *viewRegistry) {
           UIView *view = viewRegistry[reactTag];
           UIViewController *viewController = (UIViewController *)view.reactViewController;
           [viewController pushViewController:[ViewControllerXYZ new] animated:YES];
           resolve(nil);
         }
       }
     }
    
    RCT_EXPORT_METHOD
    (
      presentViewControllerXYZ:(nonnull NSNumber *)reactTag
      resolver:(RCTPromiseResolveBlock)resolve
      rejecter:(RCTPromiseRejectBlock)reject
    )
    {
      RCTUIManager *uiManager = _bridge.uiManager;
      dispatch_async(uiManager.methodQueue, ^{
        [uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *,UIView *> *viewRegistry) {
          UIView *view = viewRegistry[reactTag];
          UIViewController *viewController = (UIViewController *)view.reactViewController;
          [viewController presentViewController:[ViewControllerXYZ new] animated:YES completion:^{}];
          resolve(nil);
        }
      }
    }
    
  • 更新当前 ViewController 的 navigationItem 属性的办法
    1. 基于上述办法取到当前 Component 所属的 ViewController
    2. 通过如下代码取得它对应的 navigationItem,然后各个属性随便设
     viewController.navigationItem.title = @"Hello";
     viewController.navigationItem.prompt = @"Aloha";
    
    1. 如果希望设置 navigationItem 的 titleView 为某个 React Native Component:
     RCT_EXPORT_METHOD
     (
      setTitleView:(nonnull NSNumber *)reactTag
      props:(NSDictionary *)props
      resolver:(RCTPromiseResolveBlock)resolve
      rejecter:(RCTPromiseRejectBlock)reject
     )
     {
       UIView *titleView = [[RCTRootView alloc] initWithBridge:_bridge
                                                    moduleName:[props objectForKey:@"moduleName"]
                                             initialProperties:[props objectForKey:@"initialProperties"]];
       viewController.navigationItem.titleView = titleView;
     }
    
    1. 如果希望设置 navigationItem 的 left、right、back 按钮:
  • 以 React Native 为 view 的通用 ViewController 的实现办法
    1. ~
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容