6

We're adding react native to an existing app and are having trouble pushing a native view controller on top of another native view controller housing a react native view.

The main view controller's viewDidLoad looks like this:

-(void)viewDidLoad {
    ...
    RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation moduleName: @"ListingsView" launchOptions:nil];
    self.view = rootView;
}

The react view is a ListView where the TouchableHighlight's onPress is exported to this method on the same view controller:

RCT_EXPORT_METHOD(productClicked:(NSDictionary *)productDict)
{
    dispatch_async(dispatch_get_main_queue(),
        ^{
            SNKProduct *product = [[SNKProduct alloc] initWithDictionary:productDict];
            SNKProductViewController *vc = [[SNKProductViewController alloc] initWithProduct:product];
            [self.navigationController pushViewController:vc animated:YES];
        });

}

The method is definitely called, but the SNKProductViewController is never pushed onto the screen (no log messages). I also tried modally presenting the view controller, and am getting this console message:

Warning: Attempt to present <SNKProductViewController: 0x7feadf247d10> on <SNKProductsViewController: 0x7feada5e2a20> whose view is not in the window hierarchy!

Any help would be appreciated, thanks much!

3
  • Refer this link - stackoverflow.com/questions/29370351/… Commented Apr 13, 2015 at 4:06
  • Since you are using self to push view controller, can you confirm RCT_EXPORT_METHOD and viewDidLoad are in same class (i.e your MainViewController)? Otherwise get the topController and push SNKProductViewController. UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController; while (topController.presentedViewController) { topController = topController.presentedViewController; } [topController pushViewController:vc animated:YES]; Commented Apr 13, 2015 at 4:20
  • Unrelated, but the proper way to set your view is to use the -(void)loadView method instead of viewDidLoad. Commented May 7, 2015 at 23:01

2 Answers 2

3

After call RCT_EXPORT_MODULE macros by Reac-Native this created new instance of this module. And after call RCT_EXPORT_METHOD method this method called from another instance of module. To solve this problem, I found only one solution yet. in called method place from js search my ViewController in Hierarchy controllers:

RCT_EXPORT_MODULE(AuthController);

- (instancetype)init {
    self = [super init];
    if (self) {
    }

    return self;
}

- (void)loadView {
    self.view = [[RCTRootView alloc] initWithBundleURL:[[BCEConfigs sharedInstance] getBundleOfReactResources]
                                            moduleName:@"AuthorizationView"
                                         launchOptions:nil];
}

- (void)viewDidLoad {
    [super viewDidLoad];
}

RCT_EXPORT_METHOD(a_registrationButton) {
    [self presentRegistrationViewController];
}

- (void)presentRegistrationViewController {
    UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
    UIViewController *mainViewController = keyWindow.rootViewController.childViewControllers[0];
    BCERegistrationViewController *bceRegistrationViewController = [BCERegistrationViewController new];
    dispatch_async(dispatch_get_main_queue(), ^{
        [mainViewController presentViewController:bceRegistrationViewController animated:YES completion:nil];
    });
}

In this example my controller, which i needed, has a place this window>rootViewController>authViewController

UPD

this i found some solution how we can get current ViewController

Sign up to request clarification or add additional context in comments.

5 Comments

In the above code, you are setting AuthorizationView as your root view controller???
@Ramakrishna It does not matter, if my AuthorizationView is first VC in NavigationController it must be in Root if not didn't )
How can I set the RCTRootView in my view controller where I'm using the pushing code. And is it necessary to setting the RCTRootView for every time while I'm pushing to another view controller? Can you explain me clearly. I need it.
how can i take the navigation controller for this in app delegate plz help me.
It's question for another topic. But in my example it is native implement custom component. You can't code push native code. Its must be compiled in ur production build. You not need implement this in work. RN try fence developer from native nuance.
-1

I think you should change the -viewDidLoad method in you main view controller like this:

-(void)viewDidLoad{
  [super viewDidLoad];
  ......
  RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation moduleName: @"ListingsView" launchOptions:nil];
  [self.view addSubview:rootView];
}

That is , don't set the RCTRootView as 'self.view'; make it a subview.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.