美文网首页RN学习日志
RN - iOS原生跳转至不同的RN页面

RN - iOS原生跳转至不同的RN页面

作者: Joh蜗牛 | 来源:发表于2019-04-11 15:21 被阅读0次

    一.导入工具类

    .h文件代码:

    
    #import <React/RCTEventEmitter.h>
    #import <React/RCTBridgeModule.h>
    #import <React/RCTBridge.h>
    
    @interface RCTModel : RCTEventEmitter<RCTBridgeModule>
    //iOS向RN发送数据
    +(void)emitEventWithName:(NSString *)name andPayload:(NSDictionary *)payload;
    @end
    

    .m文件代码:

    #import "RCTModel.h"
    #import <React/RCTBridge.h>
    
    @implementation RCTModel
    @synthesize bridge = _bridge;
    
    //导出模块 不添加参数即默认认为这个oc类的名字
    RCT_EXPORT_MODULE(RTCModel)
    //导出方法,桥接到js的方法返回值类型必须是void
    
    - (NSArray<NSString *> *)supportedEvents {
        return @[@"EventReminder"]; //这里返回的将是你要发送的消息名的数组。
    }
    /*
     iOS支持方法名一样但是参数不一样的方法,视为两个不同的方法
     但是RN调用iOS这样的方法会出错的
     所以最好别把方法名声明成一样的
     */
    /**************************************** RN Call iOS ***************************************************/
    //rn跳转原生界面
    RCT_EXPORT_METHOD(RNOpenOneVC:(NSString *)msg){
        NSLog(@"RN传入原生界面的数据为:%@",msg);
        NSDictionary *dic=@{@"msg":msg};
        //主要这里必须使用主线程发送,不然有可能失效
        dispatch_sync(dispatch_get_main_queue(), ^{
            [[NSNotificationCenter defaultCenter] postNotificationName:@"RNOpenOneVC" object:nil userInfo:dic];
        });
    }
    
    RCT_EXPORT_METHOD(ToScoreVC:(NSString *)msg){
        NSLog(@"RN传入原生界面的数据为:%@",msg);
        NSDictionary *dic=@{@"title":msg};
        //主要这里必须使用主线程发送,不然有可能失效
        dispatch_sync(dispatch_get_main_queue(), ^{
            [[NSNotificationCenter defaultCenter] postNotificationName:@"ToScoreVC" object:nil userInfo:dic];
        });
    }
    /**************************************** ios 传数据给 rn ***************************************************/
    - (void)startObserving
    {
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(emitEventInternal:) name:@"event-emitted" object:nil];
    }
    - (void)stopObserving
    {
        [[NSNotificationCenter defaultCenter] removeObserver:self];
    }
    
    - (void)emitEventInternal:(NSNotification *)notification
    {
        [self sendEventWithName:@"EventReminder"
                           body:notification.userInfo];
    }
    + (void)emitEventWithName:(NSString *)name andPayload:(NSDictionary *)payload
    {
        [[NSNotificationCenter defaultCenter] postNotificationName:@"event-emitted" object:self userInfo:payload];
    }
    @end
    
    
    

    二.iOS代码

    使用viewName字段传值,用来区分两个页面(也可传入数据至RN,如示例中的url)

    以下是两个原生页面的示例:

    页面A:

    #import <React/RCTRootView.h>
    #import <React/RCTBundleURLProvider.h>
    #import "RCTDevLoadingView.h"
    #import "RCTModel.h"
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        //不显示加载view
        [RCTDevLoadingView setEnabled:NO];
    
        NSURL *jsCodeLocation;
    
        //本地虚拟机调试使用
        jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
        // 真机运行使用
        jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"index.ios" withExtension:@"jsbundle"];
    #endif
        RCTRootView *rootView =  
    [[RCTRootView alloc] initWithBundleURL: jsCodeLocation moduleName: @"SalesDaily" 
    initialProperties:@{@"viewName":@"PurchaseDaily","url":@"http://www.baidu.com"} 
    launchOptions: nil];
        self.view = rootView;
    
    }
    

    页面B:

    #import <React/RCTRootView.h>
    #import <React/RCTBundleURLProvider.h>
    #import "RCTDevLoadingView.h"
    #import "RCTModel.h"
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        //不显示加载view
        [RCTDevLoadingView setEnabled:NO];
    
        NSURL *jsCodeLocation;
    
        //本地虚拟机调试使用
        jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
        // 真机运行使用
        jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
    #endif
        RCTRootView *rootView = 
     [[RCTRootView alloc] initWithBundleURL: jsCodeLocation moduleName: @"PurchaseDaily" 
    initialProperties:@{@"viewName":@"PurchaseDaily","url":@"http://www.baidu.com"}
     launchOptions: nil];
        self.view = rootView;
    
    }
    

    三.RN代码

    1.在index.js文件中引入根文件:

    import {AppRegistry} from 'react-native';
    import Root from './Root';
    
    import {name as appName} from './app.json';
    
    AppRegistry.registerComponent(appName, () => Root);
    

    2.在根文件(root.js)中引入两个RN页面:

    根据viewName的不同,跳转至对应RN页面,并通过示例中方法,将原生页面传入的值传入对应的RN页面。
    import React, {Component} from 'react';
    
    import {AppRegistry} from 'react-native';
    import SalesDaily from "./SalesDaily";
    import PurchaseDaily from "./PurchaseDaily";
    
    export default class RootPage extends Component{
        
        render() {
            let { viewName,url} = this.props;
            if (viewName === 'SalesDaily') {
                return<SalesDaily url={url}/>;
            }else if (viewName === 'PurchaseDaily'){
                return<PurchaseDaily url={url} />;
            }
        }
    }
    
    

    相关文章

      网友评论

        本文标题:RN - iOS原生跳转至不同的RN页面

        本文链接:https://www.haomeiwen.com/subject/dozqvqtx.html