iOS集成ReactNaviteRN学习日志React native集成到iOS

iOS集成ReactNative跳转、传值

2018-08-31  本文已影响209人  精神病患者link常

iOS跳转RN界面
iOS跳转RN界面传值
iOS跳转不同的RN界面(一)
iOS跳转不同的RN界面(二)
RN界面跳转到iOS界面
iOS跳转到RN界面,继续跳转到RN界面

一、iOS跳转RN界面

- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @"iOS集成ReactNative";
    
    UIButton *button = [[UIButton alloc]initWithFrame:CGRectMake(100, 100, 200, 100)];
    [self.view addSubview:button];
    [button setTitle:@"跳转到RN界面" forState:UIControlStateNormal];
    [button addTarget:self action:@selector(jumpRNPage) forControlEvents:UIControlEventTouchUpInside];
    [button setBackgroundColor:[UIColor redColor]];
}
- (void)jumpRNPage {
    [self.navigationController pushViewController:[[RNViewController alloc]init] animated:YES];
}
- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @"ReactNative界面";

    NSURL *jsCodeLocation;
    jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle?platform=ios&dev=true"];
    RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                                        moduleName:@"iOSInstallRN"
                                                 initialProperties:nil
                                                     launchOptions:nil];
    self.view = rootView;
    
}

二、iOS跳转RN界面传值

RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                                        moduleName:@"iOSInstallRN"
                                                 initialProperties:@{@"customValue":@"value"} // 必须是object
                                                     launchOptions:nil];

ReactNative page

<Text>{this.props.customValue}</Text>

通过appProperties可以随时的修改传入的值

self.view.appProperties = @{@"imageNames":"123.png"};

三、iOS跳转不同的RN界面(一)

image.png

通过修改 http://localhost:8081/index.ios.bundle?platform=ios&dev=true

    jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle?platform=ios&dev=true"];

 jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/home.bundle?platform=ios&dev=true"];

index.ios.js

/** @format */

import {AppRegistry, StyleSheet, Text, View, TextInput,TouchableOpacity} from 'react-native';

import React, {Component} from 'react';

class Root extends Component {
    render() {
        return (
            <View style={styles.screenStyle}>
                <Text>iOS项目中集成RN{this.props.customValue}</Text>
            </View>
        );
    }
}
const styles = StyleSheet.create({
    screenStyle:{
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center'
    }
})

AppRegistry.registerComponent('iOSInstallRN', () => Root);


home.js

/** @format */

import {AppRegistry, StyleSheet, Text, View, TextInput,TouchableOpacity} from 'react-native';

import React, {Component} from 'react';
import HomeItem from  './item'

class Home extends Component {
    render() {
        return (
            <View style={styles.screenStyle}>
                <HomeItem customValue={this.props.customValue}/>
            </View>
        );
    }
}
const styles = StyleSheet.create({
    screenStyle:{
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center'
    }
})

AppRegistry.registerComponent('iOSInstallRN', () => Home);

item.js

/** @format */

import {AppRegistry, StyleSheet, Text, View, TextInput,TouchableOpacity} from 'react-native';

import React, {Component} from 'react';

export default class Item extends Component {
    render() {
        return (
            <View style={styles.screenStyle}>
                <Text>RN另外的一个界面{this.props.customValue}</Text>
            </View>
        );
    }
}
const styles = StyleSheet.create({
    screenStyle:{
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center'
    }
})

三、iOS跳转不同的RN界面(二)

通过initialProperties传值进行判断加载不同的page

/** @format */

import {AppRegistry, StyleSheet, Text, View, TextInput,TouchableOpacity} from 'react-native';

import React, {Component} from 'react';
import Mine from './mine';
import Moment from './moment';

class Root extends Component {
    render() {
        return (
            <View style={styles.screenStyle}>
                {
                    this.props.pageType === 'mine' ? <Mine/> : <Moment/>
                }
            </View>
        );
    }
}
const styles = StyleSheet.create({
    screenStyle:{
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center'
    }
})

AppRegistry.registerComponent('iOSInstallRN', () => Root);


四、RN界面跳转到iOS界面

需要桥接文件 方法一:

//
//  RNBridge.h
//  iOSInstallRN
//
//  Created by 尼古拉斯·常·穆罕默德 on 2018/8/31.
//  Copyright © 2018年 CHJ. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>

@interface RNBridge : NSObject<RCTBridgeModule>

@end

//
//  RNBridge.m
//  iOSInstallRN
//
//  Created by 尼古拉斯·常·穆罕默德 on 2018/8/31.
//  Copyright © 2018年 CHJ. All rights reserved.
//

#import "RNBridge.h"
#import <React/RCTBridge.h>

@implementation RNBridge
@synthesize bridge = _bridge;

//导出模块
RCT_EXPORT_MODULE();    //此处不添加参数即默认为这个OC类的名字

// 在RN 中调用此方法,可传值
RCT_EXPORT_METHOD(RNOpeniOSVC:(NSString *)msg){
    
    NSLog(@"RN传入原生界面的数据为:%@",msg);
    //主要这里必须使用主线程发送,不然有可能失效
    dispatch_async(dispatch_get_main_queue(), ^{
// 在AppDelegate里面接受进行处理
        [[NSNotificationCenter defaultCenter]postNotificationName:@"RNOpeniOSVC" object:nil];
    });
}

@end

index.ios.js

/** @format */

import {AppRegistry, StyleSheet, Text, View, TextInput,TouchableOpacity,NativeModules} from 'react-native';

import React, {Component} from 'react';
import Mine from './mine';
import Moment from './moment';

const RNBridge = NativeModules.RNBridge;

class Root extends Component {
    render() {
        return (
            <View style={styles.screenStyle}>
                {
                    this.props.pageType === 'mine' ? <Mine/> : <Moment/>
                }
                <TouchableOpacity onPress={()=>RNBridge.RNOpeniOSVC('RN传递给iOS的参数')}>
                    <Text>Hello World!</Text>
                    <Text>点击跳转到 iOS 界面</Text>
                </TouchableOpacity> 
            </View>
        );
    }
}
const styles = StyleSheet.create({
    screenStyle:{
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center'
    }
})

AppRegistry.registerComponent('iOSInstallRN', () => Root);

由于RN调用的桥接文件的方法中是发送的通知,所以......
在iOS原生界面中,可以写在 AppDelegate.m 也可以写在iOS最新停留的界面中,接受通知,进行操作。在适当的时候进行释放通知

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(jumpiOSPageVC) name:@"RNOpeniOSVC" object:nil];

- (void)jumpiOSPageVC {
    iOSViewController *iosViewCtrl = [[iOSViewController alloc]init];
    [self.navigationController pushViewController:iosViewCtrl animated:YES];
}

需要桥接文件 方法二 推荐:

新建桥接RNBridge.m文件(上一个方法是创建了.h、.m)

重点⚠️@interface RCT_EXTERN_MODULE(RERNBridgeManager, NSObject)
RERNBridgeManager具体的实现方法类,如果方法过多,可以新建RERNBridgeManager的分类进行解决

#import <React/RCTBridgeModule.h>

@interface RCT_EXTERN_MODULE(RERNBridgeManager, NSObject) 

// rn跳转到原生承载的rn
RCT_EXTERN_METHOD(jumpScreen:(NSDictionary*)dic)
//rn返回原生上一页
RCT_EXTERN_METHOD(closeScreen)
//rn返回原生根界面
RCT_EXTERN_METHOD(closeScreenToRoot)
// rn 返回上一级传值
RCT_EXTERN_METHOD(closeScreenWithParams:(NSDictionary *)dic)


@end

五、iOS跳转到RN界面,继续跳转到RN界面

需要添加react-navigation

请看这边文章

上一篇下一篇

猜你喜欢

热点阅读