React-Native iOS – 如何通过按下按钮从React-Native视图导航到非React-Native视图(本机iOS视图控制器)?
RN doco和其他示例显示了如何从本机iOS视图控制器启动React-Native视图,但不是相反。 有人可以解释我怎么做到这一点?
我能够弄清楚这一点。 在我的例子中,我使用我自己的Swift本机视图控制器的Obj-C基础项目(这是RN默认值)。 我的解决方案就在这里,以防其他人出现:
简单地说,答案是使用RTCBridge模块允许RN javascript调用本机iOS方法。
以下是组件的概述,然后是实现:
- AppDelegate.h / .m – 初始化初始RN视图的RN javascript索引文件,还设置了将根视图控制器交换到本机视图控制器的方法(此方法将从RTCBridge模块调用。
- MyViewController.swift – 具有标准实现的普通UIViewController。
- MyProject-Bridging-Header.h – 提供Obj-C < - > Swift通信
- ChangeViewBridge.h / .m – 这提供了绑定,允许您从RN javascript调用本机iOS方法
- index.ios.js – 初始化自定义RCTBridge模块并调用绑定方法,按下按钮切换到本机视图。
AppDelegate.h
#import @interface AppDelegate : UIResponder { NSDictionary *options; UIViewController *viewController; } @property (nonatomic, strong) UIWindow *window; - (void) setInitialViewController; - (void) goToRegisterView; // called from the RCTBridge module @end
AppDelegate.m
#import "AppDelegate.h" #import #import #import "FidoTestProject-Swift.h" // Xcode generated import to reference MyViewController.swift from Obj-C @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { options = launchOptions; [self setInitialViewController]; return YES; } - (void) setInitialViewController { NSURL *jsCodeLocation; jsCodeLocation = [NSURL URLWithString:@"http://192.168.208.152:8081/index.ios.bundle?platform=ios&dev=true"]; RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation moduleName:@"FidoTestProject" initialProperties:nil launchOptions:options]; self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; UIViewController *rootViewController = [UIViewController new]; rootViewController.view = rootView; self.window.rootViewController = rootViewController; viewController = rootViewController; [self.window makeKeyAndVisible]; } // this method will be called from the RCTBridge - (void) goToNativeView { NSLog(@"RN binding - Native View - MyViewController.swift - Load From "main" storyboard); UIViewController *vc = [UIStoryboard storyboardWithName:@"main" bundle:nil].instantiateInitialViewController; self.window.rootViewController = vc; } @end
MyViewController.swift
class RegisterViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() print("MyViewController loaded...") // standard view controller will load from RN } }
MyProject的桥接,Header.h
@import Foundation; @import UIKit; @import CoreLocation; @import AVFoundation; #import "React/RCTBridge.h" #import "React/RCTBridgeModule.h" #import "React/RCTBundleURLProvider.h" #import "React/RCTRootView.h" #import "AppDelegate.h"
ChangeViewBridge.h
#import @interface ChangeViewBridge : NSObject - (void) changeToNativeView; @end
ChangeViewBridge.m
#import "RegisterBridge.h" #import "FidoTestProject-Swift.h" #import "AppDelegate.h" @implementation ChangeViewBridge // reference "ChangeViewBridge" module in index.ios.js RCT_EXPORT_MODULE(ChangeViewBridge); RCT_EXPORT_METHOD(changeToNativeView) { NSLog(@"RN binding - Native View - Loading MyViewController.swift"); AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate; [appDelegate goToNativeView]; } @end
index.ios.js
/** * Sample React Native App * https://github.com/facebook/react-native * @flow */ 'use strict'; import React, { Component } from 'react'; import { AppRegistry, StyleSheet, Alert, Text, View, NativeModules, TouchableHighlight } from 'react-native'; export default class FidoTestProject extends Component { constructor(props) { super(props) this.done = false; } _changeView() { this.done = true; this.render(); NativeModules.ChangeViewBridge.changeToNativeView(); } render() { if (!this.done) { return ( this._changeView()}> Press to Change to Native View ); } else { return ( ); } } }; const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#F5FCFF', } }); AppRegistry.registerComponent('FidoTestProject', () => FidoTestProject);