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!

gogi
  • 61
  • 2
  • 2
  • Refer this link - http://stackoverflow.com/questions/29370351/react-native-touchable-press-event-not-responding-after-pushed-to-stack – Uttam Sinha Apr 13 '15 at 04: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]; – Nova Apr 13 '15 at 04:20
  • Unrelated, but the proper way to set your view is to use the -(void)loadView method instead of viewDidLoad. – Brandon May 07 '15 at 23:01

2 Answers2

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

Community
  • 1
  • 1
Bimawa
  • 3,535
  • 2
  • 25
  • 45
  • In the above code, you are setting AuthorizationView as your root view controller??? – Ramakrishna Sep 22 '16 at 14:06
  • @Ramakrishna It does not matter, if my AuthorizationView is first VC in NavigationController it must be in Root if not didn't ) – Bimawa Sep 23 '16 at 04:32
  • 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. – Ramakrishna Sep 23 '16 at 06:28
  • how can i take the navigation controller for this in app delegate plz help me. – Ramakrishna Sep 23 '16 at 07:00
  • 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. – Bimawa Sep 23 '16 at 11:12
-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.

Mindy
  • 429
  • 4
  • 6