首页 > 解决方案 > 在 View Controller 中运行 React Native

问题描述

我正在用 react native 构建一个测试应用程序,其中主视图是 React Native,工具栏是 Native Part(Android/iOS)。就像这个ct图像一样,在 Android 中我使用 Fragment 运行 react native 并将片段附加到主应用程序。我使用了这个答案。但现在我需要为 iOS 做同样的事情,任何有用的链接或博客都会有所帮助。

[编辑]:在@Murilo Paixão 建议后,我将 AppDelegate 更改为以下内容:-

let rootView = RCTRootView(bundleURL: jsCodeLocation, moduleName: "swiftdemoapp", initialProperties: nil, launchOptions: launchOptions)
let rootViewController = TwtViewController()
rootViewController.view = rootView

其中 TwtViewController 继承自 UiViewController 并有一个连接到它的 stroyboard。

在此处输入图像描述

所以现在当我运行我的应用程序时,整个屏幕都被本机反应占据了如何调整大小或者我需要放置子视图控制器以便我可以看到本机标签。

标签: iosswiftreact-native

解决方案


假设您有以下组件:

import React from 'react';
import { AppRegistry, View, Text } from 'react-native';

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#FFFFFF',
  },
});

class SimpleTextComponent extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        <Text>{this.props.text}</Text>
      </View>
    );
  }
}

// module name
AppRegistry.registerComponent('SimpleTextComponent', () => SimpleTextComponent);

现在你想将它加载到一个普通UIViewController的 iOS 中。您只需要执行以下操作:

// Run this before presenting the view controller inside your native iOS app.

// In this case, index.bundle matches the index.js file that contains your component code
NSURL *jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.bundle?platform=ios"];

// Provide the same module name used on AppRegistry
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                                    moduleName:@"SimpleTextComponent"
                                             initialProperties:@{@"text": "React Native Content"}
                                                 launchOptions:nil];

UIViewController *viewController = [UIViewController new];
viewController.view = rootView;
[self presentViewController:viewController animated:YES completion:nil];

你可以在react native page上看到更多。

编辑1:

所以,我看到你在混合 react-native 和原生 iOS 代码时仍然存在问题,我将通过一个更完整的示例,我真的希望这会有所帮助:)

让我们通过三个简单的步骤来构建这个应用程序:

在此处输入图像描述

这个橙色视图是使用 Xcode 的界面构建器添加的,蓝色视图来自 react-native 组件。另外,请注意导航栏,它是原生的UINavigationController

步骤1

使用关联的 xib 文件创建视图控制器并添加标签。

转到New File并选择Cocoa Touch Class在此处输入图像描述

然后,在子类上选择UIViewController和标记Also create XIB file

注意:我坚持使用 Objective-C,因为它更容易处理 react-native,但你也可以使用 Swift 来完成 :)

在此处输入图像描述

现在,您应该获得一个带有 XIB 文件的视图控制器的空模板。

第2步

在界面生成器上为您的视图添加标签,它可以如下所示:

在此处输入图像描述

然后,修改您的AppDelegate.m并将您的新视图控制器嵌入到 a 中UINavigationController,并将其设置为您的根视图控制器:

#import "AppDelegate.h"
#import "NativeLabelViewController.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  NativeLabelViewController *rootViewController = [[NativeLabelViewController alloc] initWithNibName:@"NativeLabelViewController"
                                                                                              bundle:[NSBundle mainBundle]];
  UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController: rootViewController];

  self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
  self.window.rootViewController = navigationController;
  [self.window makeKeyAndVisible];

  return YES;
}

@end

第 3 步

现在让我们在视图 \o/ 中嵌入一个 react 组件。

首先,创建一个RCTRootView并用一些 js 代码填充它,如下所示:

注意:我只是使用了与上一个示例相同的组件。

// index here matches the index.js file on your project's root.
NSURL *jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
UIView *reactView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                                moduleName:@"SimpleTextComponent"
                                         initialProperties:@{@"text": @"I came from React Native \\o/"}
                                             launchOptions:nil];

现在,为它添加一些约束。我选择匹配超级视图的底部,前导和尾随,并匹配顶部约束的垂直中心:

// Setup react view constraints
[self.view addSubview:reactView];
[reactView setTranslatesAutoresizingMaskIntoConstraints:NO];

NSLayoutConstraint *leadingConstraint = [reactView.leadingAnchor constraintEqualToAnchor:[self.view leadingAnchor]];
NSLayoutConstraint *bottomConstraint = [reactView.bottomAnchor constraintEqualToAnchor:[self.view bottomAnchor]];
NSLayoutConstraint *trailingConstraint = [reactView.trailingAnchor constraintEqualToAnchor:[self.view trailingAnchor]];
NSLayoutConstraint *topConstraint = [reactView.topAnchor constraintEqualToAnchor:[self.view centerYAnchor]];

[self.view addConstraints:@[leadingConstraint, bottomConstraint, trailingConstraint, topConstraint]];
[self.view setNeedsUpdateConstraints];

最终文件应如下所示:

#import "NativeLabelViewController.h"
#import <React/RCTRootView.h>
#import <React/RCTBundleURLProvider.h>

@interface NativeLabelViewController ()

@end

@implementation NativeLabelViewController

- (void)viewDidLoad {
  [super viewDidLoad];

  self.title = @"Mixed react-native and iOS views";
  [self setupReactView];
}

- (void)setupReactView {
  NSURL *jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
  UIView *reactView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                                  moduleName:@"SimpleTextComponent"
                                           initialProperties:@{@"text": @"I came from React Native \\o/"}
                                               launchOptions:nil];

  // Setup react view constraints
  [self.view addSubview:reactView];
  [reactView setTranslatesAutoresizingMaskIntoConstraints:NO];

  NSLayoutConstraint *leadingConstraint = [reactView.leadingAnchor constraintEqualToAnchor:[self.view leadingAnchor]];
  NSLayoutConstraint *bottomConstraint = [reactView.bottomAnchor constraintEqualToAnchor:[self.view bottomAnchor]];
  NSLayoutConstraint *trailingConstraint = [reactView.trailingAnchor constraintEqualToAnchor:[self.view trailingAnchor]];
  NSLayoutConstraint *topConstraint = [reactView.topAnchor constraintEqualToAnchor:[self.view centerYAnchor]];

  [self.view addConstraints:@[leadingConstraint, bottomConstraint, trailingConstraint, topConstraint]];
  [self.view setNeedsUpdateConstraints];
}

@end

而已。运行它,结果应该如下所示:

在此处输入图像描述


推荐阅读