Native View 呈现 React Native 视图 [英] Native View Presenting a React Native View
问题描述
有谁知道我如何可以有一个原生 UIViewController 呈现或推送一个 React Native 视图,然后在两者之间来回切换?
Does anyone know how I can have a native UIViewController present or push a React Native view, and go back and forth between the two?
如果可能,我想在 UIViewController 中加载 React Native 视图,这样我就可以保留导航栏,但使用 React Native 视图.
If possible, I'd like to load the React Native view inside a UIViewController so I can retain my navigation bar, but use the React Native view.
我一直在阅读文档,但是我找不到任何有效的东西.
I've been reading the documentation, but I have not been able to find anything that works.
我尝试了以下组合:
// RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:nil launchOptions:nil];
// RCTRootView *reactView = [[RCTRootView alloc] initWithBridge:bridge moduleName:@"My Test" initialProperties:nil];
NSURL *jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];
RCTRootView *reactView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:@"My Test"
initialProperties:nil
launchOptions:nil];
reactView.frame = self.view.frame;
[self.view addSubview:reactView];
我不太确定我是否理解它如何知道我想要它使用什么 .js React 文件,或者我如何指定它.
I'm not quite sure I understand how it knows what .js React file I want it to use, or how I specify that.
推荐答案
要使这种方法起作用,您至少需要:
To have this kind of approach working you'll at least need:
- 访问您的所有
RCTRootView
都可以共享的网桥.如果您希望每个根视图从同一个包中加载不同的 RN 组件 - 它们需要共享相同的RCTBridge
- 一个
UIViewController
,它的视图是一个RCTRootView
.然后,您可以将此视图控制器用作导航控制器的根目录,以模态方式显示它,就像您已经尝试过的那样.
- Access to a bridge that all your
RCTRootView
s can share. If you want each root view to load a different RN component from the same bundle - they need to share the sameRCTBridge
- A
UIViewController
that its view is aRCTRootView
. You can then use this view controller as the root of a navigation controller, show it modally etc. like you've already tried to do.
让我们看一下这个想法的一个非常简单的示例实现.
标题:
#import <Foundation/Foundation.h>
#import "RCTBridge.h"
@interface ReactBridgeManager : NSObject
@property (nonatomic, strong, readonly) RCTBridge *bridge;
-(instancetype)initWithBundleURL:(NSURL *)bundleURL launchOptions:(NSDictionary *)launchOptions;
@end
实施:
#import "ReactBridgeManager.h"
@interface ReactBridgeManager () <RCTBridgeDelegate>
@property (nonatomic, strong, readwrite) RCTBridge *bridge;
@property (nonatomic, strong) NSURL *bundleURL;
@end
@implementation ReactBridgeManager
- (instancetype)initWithBundleURL:(NSURL *)bundleURL launchOptions:(NSDictionary *)launchOptions
{
self = [super init];
if (self)
{
self.bundleURL = bundleURL;
self.bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
}
return self;
}
#pragma mark - RCTBridgeDelegate methods
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
return self.bundleURL;
}
@end
2.控制反应根视图的视图控制器
标题
#import <UIKit/UIKit.h>
#import "RCTBridge.h"
@interface ReactViewController : UIViewController
- (instancetype)initWithBridge:(RCTBridge *)bridge moduleName:(NSString*)moduleName initialProps:(NSDictionary*)initialProps;
@end
实施
#import "ReactViewController.h"
#import "RCTRootView.h"
@implementation ReactViewController
- (instancetype)initWithBridge:(RCTBridge *)bridge moduleName:(NSString*)moduleName initialProps:(NSDictionary*)initialProps
{
self = [super init];
if(self)
{
self.view = [[RCTRootView alloc] initWithBridge:bridge moduleName:moduleName initialProperties:initialProps];
}
return self;
}
@end
3.用法示例
您现在可以在需要时使用您的反应组件名称创建 ReactViewController
的实例(这是在 JS 端的 RN AppRegistry
中注册的组件)并推送它进入您的本机导航堆栈,将其显示为模态等.
3. Usage example
You can now create instances of ReactViewController
where necessary with your react component name (this is a component that was registered in RN AppRegistry
on the JS side) and push it into your native navigation stack, show it as a modal, etc.
//when your app is initialized, create the bridge manager and hold a reference to it.
ReactBridgeManager *bridgeManager = [[ReactBridgeManager alloc] initWithBundleURL:jsCodeLocation launchOptions:launchOptions];
//create a view controller that's controlling a react root view
ReactViewController *reactViewController = [[ReactViewController alloc] initWithBridge:bridgeManager.bridge moduleName:@"MyComponent" initialProps:nil];
更上一层楼
你可以看看 React Native Navigation 基本上使用相同的概念为反应原生应用程序提供完全原生的导航解决方案.免责声明:我是开发这个包的团队的一员:)
Taking it to the next level
You can take a look at React Native Navigation which basically uses the same concept to allow a fully native navigation solution for react-native apps. Disclaimer: I'm part of the team that develops this package :)
这篇关于Native View 呈现 React Native 视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!