[React Native] 在 iOS 中,关于 ViewCo
2016-06-09 本文已影响2386人
瑶柱活到老供楼到老
- 获得当前 Component 所属 ViewController 的办法(这是后续各个操作的基础)
- 创建或找到一个现成的 BridgeModule 类
- 在该 BridgeModule 类的 .m 文件中,确保包含
#import "UIView+React.h"
- 在 @implementation 中,确保包含
@synthesize bridge = _bridge;
- 在 @implementation 中,RCT_EXPORT_METHOD 一个 Bridge 方法
RCT_EXPORT_METHOD( sometingToDoWithTheViewControllerOfTheComponent:(nonnull NSNumber *)reactTag // Component 对象的 reactTag resolver:(RCTPromiseResolveBlock)resolve // 这行 rejecter:(RCTPromiseRejectBlock)reject // 和这行是可选的,如果需要在执行完毕后给 JavaScript 通知的话,就带上 ) { // 实现后文详述 }
- 在 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 的办法
- 基于上述办法取到当前 Component 所属的 ViewController
- 通过如下代码取得它所属的 navigationController,调用它的 pushViewController 或 presentViewController 方法即可
[viewController.navigationController pushViewController:anotherViewController animated:YES]; // 跳转 [viewController.navigationController presentViewController:anotherViewController animated:YES completion:^{}] ;// 弹出
- 完整代码如下:
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 属性的办法
- 基于上述办法取到当前 Component 所属的 ViewController
- 通过如下代码取得它对应的 navigationItem,然后各个属性随便设
viewController.navigationItem.title = @"Hello"; viewController.navigationItem.prompt = @"Aloha";
- 如果希望设置 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; }
- 如果希望设置 navigationItem 的 left、right、back 按钮:
- 以 React Native 为 view 的通用 ViewController 的实现办法
- ~