React-Native: Dismiss/Exit React-Native View back

2020-06-03 04:04发布

问题:

I have an existing app that I am working on integrating React-Native for a portion of it. I am having trouble understanding how to 'exit' react-native and get back to a native view.

Here's some code:

// Main objective-c code that bootstraps the react-native view. This view is loaded as a modal view.
MainViewController.m:

- (void)viewDidLoad {
    [super viewDidLoad];

    RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation moduleName:@"IndexApp" initialProperties:props launchOptions:nil];

    rootView.frame = CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height-49);
    [self.view addSubview:rootView];

}

My initial react views are such:

render() {
  return (
      <Navigator
          style={styles.container}
...

I have a right-nav button on the Navigator that I would like to "dismiss" the react view and the underlying MainViewController native view.

I have tried a callback to MainViewController from the react view like so, but without avail:

RCT_EXPORT_METHOD(dismiss:(NSString *)name location:(NSString *)location)
{
    NSLog(@"dismiss...");
    // these don't do anything
    //[self dismissViewControllerAnimated:YES completion:nil];
    //[self.navigationController popViewControllerAnimated:YES];
    // anything with _rootView doesn't do anything, i.e. _rootView removeFromSuperview];

}

Any help with an approach to 'exit' the react-native view and get back into native views would be appreciated.

回答1:

The only way I've found this works is this

The gist of it is:

  1. Create a NotificationManager class in Obj-C and expose it as React Module
  2. In the ViewController register for a notification which when receives triggers [self dismissViewController..]


回答2:

You need to run the pop or dismiss on the main thread:

RCT_EXPORT_METHOD(dismiss:(NSString *)name location:(NSString *)location)
{
    NSLog(@"dismiss...");
    dispatch_async(dispatch_get_main_queue(), ^{
        [self dismissViewControllerAnimated:YES completion:nil];

        // use pop instead if this view controller was pushed onto a navigation controller
        //[self.navigationController popViewControllerAnimated:YES];
    }
}


回答3:

NOTE: THIS DOESN"T WORK - I've left this here as an example of what doesn't work. Check my other answer for an approach that works.

If you present MainViewController this way, popViewController: should work

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


MainViewController *rootViewController = [MainViewController new];
rootViewController.view = reactView;

[[self navigationController] pushViewController:rootViewController animated:YES];