【问题标题】:Run React Native inside View Controller在 View Controller 中运行 React Native
【发布时间】:2019-01-25 00:10:48
【问题描述】:

我正在用 react native 构建一个测试应用程序,其中主视图是 React Native,工具栏是 Native Part(Android/iOS)。就像这个 图像,所以在 Android 中我使用 Fragment 运行 react native 并附加片段到主应用程序。我使用了this 答案。但现在我需要为 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。

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

【问题讨论】:

    标签: ios swift react-native


    【解决方案1】:

    假设您有以下组件:

    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);
    

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

    // 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 文件的视图控制器的空模板。

    第二步

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

    然后,修改您的 AppDelegate.m 并将您的新视图控制器嵌入到 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
    

    第三步

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

    首先,创建一个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];
    

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

    // 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
    

    就是这样。运行它,结果应该如下所示:

    【讨论】:

    • 感谢您的详细示例,它就像一个魅力:-)
    • 能否检查组件“SimpleTextComponent”是否存在?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-19
    • 2016-03-14
    • 2017-12-30
    • 1970-01-01
    • 2020-09-08
    • 1970-01-01
    相关资源
    最近更新 更多