Native View 呈现 React Native 视图 [英] Native View Presenting a React Native View

查看:41
本文介绍了Native View 呈现 React Native 视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有谁知道我如何可以有一个原生 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:

  1. 访问您的所有 RCTRootView 都可以共享的网桥.如果您希望每个根视图从同一个包中加载不同的 RN 组件 - 它们需要共享相同的RCTBridge
  2. 一个 UIViewController,它的视图是一个 RCTRootView.然后,您可以将此视图控制器用作导航控制器的根目录,以模态方式显示它,就像您已经尝试过的那样.
  1. Access to a bridge that all your RCTRootViews can share. If you want each root view to load a different RN component from the same bundle - they need to share the sameRCTBridge
  2. A UIViewController that its view is a RCTRootView. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆