React-Native iOS - How can I navigate to a non-React-Native view (native iOS view controller) from a React-Native view with a button press?

前端 未结 3 1843
清歌不尽
清歌不尽 2020-12-03 05:37

The RN doco and other examples show how to launch a React-Native view from a native iOS view controller, but not the other way around. Can someone explain how I can do this

3条回答
  •  鱼传尺愫
    2020-12-03 06:31

    An update to this answer with Swift 5. Thanks to

    https://github.com/facebook/react-native/issues/1148#issuecomment-102008892

    https://stackoverflow.com/a/46007680/7325179 - answer by MStrapko

    https://codersera.com/blog/react-native-bridge-for-ios/?unapproved=2851&moderation-hash=77e42524b246d2fda0f763a496156db5#comment-2851 - an elaborate explanation and tutorial by William Dawson

    Getting into the Solution:

    In AppDelegate.swift

    import Foundation
    import UIKit
    
    @UIApplicationMain
    class AppDelegate: UIResponder, UIApplicationDelegate {
      var window: UIWindow?
      var bridge: RCTBridge!
      
      func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        let jsCodeLocation: URL
        
        jsCodeLocation = RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index.js", fallbackResource:nil)
        let rootView = RCTRootView(bundleURL: jsCodeLocation, moduleName: "RNModuleName", initialProperties: nil, launchOptions: launchOptions)
        
        self.window = UIWindow(frame: UIScreen.main.bounds)
        let reactNativeViewController = UIViewController()
        reactNativeViewController.view = rootView
        let reactNavigationController = UINavigationController(rootViewController: reactNativeViewController)
        self.window?.rootViewController = reactNavigationController
        self.window?.makeKeyAndVisible()
        
        return true
      }
    //  func goToReactNative() {
    //    window?.rootViewController?.dismiss(animated: true)
    //  }
      func goNativeStoryboard() {
        DispatchQueue.main.async {
          let vc = UIStoryboard(name: "Main", bundle: nil).instantiateInitialViewController()
          if let vc = vc {
            (self.window?.rootViewController as? UINavigationController)?.pushViewController(vc, animated: true)
          }
        }
      }
    }
    

    YourViewController.swift

    Your regular code
    

    YourApp-Bridging-Header. Please note there are some extra headers as well, that you might not need.

    #import "React/RCTBridgeModule.h"
    #import "React/RCTBridge.h"
    #import "React/RCTEventDispatcher.h"
    #import "React/RCTRootView.h"
    #import "React/RCTUtils.h"
    #import "React/RCTConvert.h"
    #import "React/RCTBundleURLProvider.h"
    #import "RCTViewManager.h"
    #import "React/RCTEventEmitter.h"
    

    ConnectingFile.swift

    @objc(Connect)
    class Connect: NSObject {
      @objc func goToNative() -> Void {
        DispatchQueue.main.async {
          if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
            appDelegate.goNativeStoryboard()
          }
        }
      }
    }
    

    Connect.m

    #import "React/RCTViewManager.h"
    @interface RCT_EXTERN_MODULE(Connect, RCTViewManager)
    RCT_EXTERN_METHOD(goToNative)
    
    @end
    

    ReactNativeFile.js

    import React, { Component } from 'react';
    import { StyleSheet, View, NativeModules, Text, TouchableOpacity } from 'react-native';
    const { Connect } = NativeModules;
    export default class Feed extends Component {
      constructor(props) {
        super(props)
        this.done = false;
      }
      _changeView() {
        this.done = true;
        Connect.goToNative()
      }
      render() {
        return (
          
             this._changeView()}>
              
                Press to Change to Native View
                
            
          
        );
      }
    }
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        backgroundColor: 'pink',
        alignItems: 'center',
        justifyContent: 'center',
      }
    });
    

    That was it, it worked for me, hope it works for you as well. Thanks again to all the sources of references.

提交回复
热议问题