Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React-Native Hybrid App: Pop UIViewController that embeds RCTRootView

I'm integrating components in an existing iOS app written in Objective-C/Swift.

As a root view controller of my app, I use an UINavigationController.

In one of the multiple view controllers of my app, I have a button that push a View Controller in the Navigation Controller that contains the following code:

@objc class ReactNativeViewController: UIViewController {
  override func viewDidLoad() {
    let jsCodeLocation = NSURL(string: "http://localhost:8081/index.ios.bundle?platform=ios&dev=true")

    let contactsView = RCTRootView(bundleURL: jsCodeLocation, moduleName: "MainComponent", initialProperties: nil, launchOptions: nil)

    self.view.addSubview(contactsView)
    contactsView.frame = self.view.bounds;
  }
}

MainComponent returns a Navigator that manage multiple React-Native components:

return (
  <Navigator
    initialRoute={initialRoute}
    renderScene={(route, navigator) => {
      if (route.component) {
        return <route.component navigator={navigator} {...route.passProps} />;
      }
    }}
    navigationBar={
      <Navigator.NavigationBar
        routeMapper={this.NavigationBarRouteMapper}
        style={styles.navBar}
      />
    }
  />
);

That workflow works fine. The only thing I need is a way to pop ReactNativeViewController from my UINavigationController when the button Back has been hit on the main React-Native component.

I tried the following but with no luck:

  • Create a Native Module with a single method popLastViewController that pop the displayed UIViewController that is displayed from the UINavigationController:

    @implementation RNNavigationControllerBridge
    
    RCT_EXPORT_MODULE()
    
    RCT_EXPORT_METHOD(popLastViewController) {
      UINavigationController *navigationController = (UINavigationController *)[[[[UIApplication sharedApplication] delegate] window] rootViewController];
    
      [navigationController popViewControllerAnimated:NO];
    }
    
    @end
    
  • Call the above method when back button has been hit:

    onPress={() => {
      if (index === 0) {
        NativeViewsManager.popLastViewController();
      } else {
        navigator.pop();
      }
    }}
    

But that doesn't work.

Any suggestion?

like image 660
Jean Lebrument Avatar asked Nov 11 '15 12:11

Jean Lebrument


1 Answers

Problem solved!

RCT_EXPORT_METHOD(popLastViewController) {
  dispatch_async(dispatch_get_main_queue(), ^{
    UINavigationController *navigationController = (UINavigationController *)[[[[UIApplication sharedApplication] delegate] window] rootViewController];

    [navigationController popViewControllerAnimated:YES];
  });
}
like image 80
Jean Lebrument Avatar answered Oct 23 '22 21:10

Jean Lebrument