UINavigationController 在 RCT_EXPORT_METHOD 中为零(React Native)

Posted

技术标签:

【中文标题】UINavigationController 在 RCT_EXPORT_METHOD 中为零(React Native)【英文标题】:UINavigationController is nil in RCT_EXPORT_METHOD (React Native) 【发布时间】:2017-05-24 13:35:42 【问题描述】:

我有一个项目,我将本机代码与 React Native 混合。我这样展示 React 视图:

self.reactView = [[RCTRootView alloc] initWithBridge:bridge moduleName:@"DemoPage" initialProperties:initialProperties];
[self.view addSubview:self.reactView];

以上工作正常,视图显示正确。视图是项目列表。选择列表项时,它应响应返回我的视图控制器,我将推送本机视图控制器。我使用这样的本机模块来做到这一点:

RCT_EXPORT_MODULE(NavigationUtils);

RCT_EXPORT_METHOD(navigateWithParameters:(NSString *)parameters)

    ViewController *viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
    [self.navigationController pushViewController:viewController animated:YES];

我的问题是,当尝试 pushViewController: 时,self.navigationControllernil,所以推送什么都不做。

presentViewController: 也不起作用。

self.navigationController viewWillAppear:viewDidAppear: 中不是nil

有人知道我如何从 React Native 模块推送新的原生视图控制器吗?

这是视图层次结构的 recursiveDescription 的编辑版本。

<UIWindow: 0x102a10970; frame = (0 0; 414 736); autoresize = W+H; tintColor = UIExtendedSRGBColorSpace 0.313725 0.52549 0.764706 1; gestureRecognizers = <NSArray: 0x17405ab20>; layer = <UIWindowLayer: 0x17422ae20>>
   | <UIView: 0x102b55ff0; frame = (0 0; 414 736); autoresize = W+H; gestureRecognizers = <NSArray: 0x17064e550>; layer = <CALayer: 0x170631220>>
   |    | <UIView: 0x102b6b580; frame = (0 0; 414 736); autoresize = W+H; layer = <CALayer: 0x170631260>>
   |    |    | <UILayoutContainerView: 0x102b689d0; frame = (0 0; 314 736); hidden = YES; autoresize = RM+H; gestureRecognizers = <NSArray: 0x17064d410>; layer = <CALayer: 0x17062f4e0>>
   |    |    |    | <UINavigationTransitionView: 0x102b6ab20; frame = (0 0; 314 736); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x170631100>>
   |    |    |    |    | <UIViewControllerWrapperView: 0x102b74ad0; frame = (0 0; 314 736); autoresize = W+H; layer = <CALayer: 0x1706350c0>>
   |    |    |    |    |    | <UITableView: 0x10388f400; frame = (0 0; 314 736); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x1748569e0>; layer = <CALayer: 0x17482a600>; contentOffset: 0, 0; contentSize: 314, 630>
   |    |    |    |    |    |    | ...Cells and seperators
   |    |    |    | <UINavigationBar: 0x102b68b90; frame = (0 20; 314 44); opaque = NO; autoresize = W; gestureRecognizers = <NSArray: 0x17064db00>; layer = <CALayer: 0x170630c60>>
   |    |    |    |    | <_UIBarBackground: 0x102b68e40; frame = (0 -20; 314 64); userInteractionEnabled = NO; layer = <CALayer: 0x170630ce0>>
   |    |    |    |    |    | <UIImageView: 0x102b69450; frame = (0 64; 314 0.333333); userInteractionEnabled = NO; layer = <CALayer: 0x170630d20>> - (null)
   |    |    |    |    |    | <UIVisualEffectView: 0x102b69640; frame = (0 0; 314 64); layer = <CALayer: 0x170630d40>>
   |    |    |    |    |    |    | <_UIVisualEffectBackdropView: 0x102b69a80; frame = (0 0; 314 64); autoresize = W+H; userInteractionEnabled = NO; layer = <UICABackdropLayer: 0x170630da0>>
   |    |    |    |    |    |    | <_UIVisualEffectFilterView: 0x102b6a380; frame = (0 0; 314 64); autoresize = W+H; userInteractionEnabled = NO; layer = <CALayer: 0x170630f60>>
   |    |    |    |    |    |    | <_UIVisualEffectFilterView: 0x102a850b0; frame = (0 0; 314 64); alpha = 0.85; autoresize = W+H; userInteractionEnabled = NO; layer = <CALayer: 0x17482c3e0>>
   |    |    |    |    | <UIImageView: 0x102a7e940; frame = (89 3.33333; 136 37.6667); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x174829240>> - (null)
   |    |    |    |    | <_UINavigationBarBackIndicatorView: 0x102b6a730; frame = (12 11.6667; 13 21); alpha = 0; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x170631000>> - Back
   |    |    | <MMDrawerCenterContainerView: 0x102b6b8d0; frame = (0 0; 414 736); autoresize = W+H; layer = <CALayer: 0x1706312c0>>
   |    |    |    | <UILayoutContainerView: 0x102aafb40; frame = (0 0; 414 736); autoresize = W+H; gestureRecognizers = <NSArray: 0x170441890>; layer = <CALayer: 0x17422ad60>>
   |    |    |    |    | <UINavigationTransitionView: 0x102ab02e0; frame = (0 0; 414 736); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x17422adc0>>
   |    |    |    |    |    | <UIViewControllerWrapperView: 0x102a828b0; frame = (0 0; 414 736); autoresize = W+H; layer = <CALayer: 0x174a201a0>>
   |    |    |    |    |    |    | <UIView: 0x102b98e20; frame = (0 0; 414 736); autoresize = W+H; layer = <CALayer: 0x170c209a0>>
   |    |    |    |    |    |    |    | <RCTRootView: 0x102b9a8d0; frame = (0 64; 414 736); autoresize = W+H; layer = <CALayer: 0x170c221c0>>
   |    |    |    |    |    |    |    |    | ...subviews of RCTRootView
   |    |    |    |    | <UINavigationBar: 0x102aaf160; frame = (0 20; 414 44); opaque = NO; autoresize = W; gestureRecognizers = <NSArray: 0x174258690>; layer = <CALayer: 0x17422a720>>
   |    |    |    |    |    | <_UIBarBackground: 0x102aaf410; frame = (0 -20; 414 64); userInteractionEnabled = NO; layer = <CALayer: 0x17422ab40>>
   |    |    |    |    |    |    | <UIImageView: 0x102a9e1e0; frame = (0 64; 414 0.333333); userInteractionEnabled = NO; layer = <CALayer: 0x17422a9c0>> - (null)
   |    |    |    |    |    |    | <UIVisualEffectView: 0x102a9e3d0; frame = (0 0; 414 64); layer = <CALayer: 0x174230c60>>
   |    |    |    |    |    |    |    | <_UIVisualEffectBackdropView: 0x102a98840; frame = (0 0; 414 64); autoresize = W+H; userInteractionEnabled = NO; layer = <UICABackdropLayer: 0x1742327c0>>
   |    |    |    |    |    |    |    | <_UIVisualEffectFilterView: 0x102a98ba0; frame = (0 0; 414 64); autoresize = W+H; userInteractionEnabled = NO; layer = <CALayer: 0x174233560>>
   |    |    |    |    |    |    |    | <_UIVisualEffectFilterView: 0x102ab1380; frame = (0 0; 414 64); alpha = 0.85; autoresize = W+H; userInteractionEnabled = NO; layer = <CALayer: 0x174233660>>
   |    |    |    |    |    | <<UINavigationItemView: 0x102ab04c0; frame = (169.333 8; 75.3333 27); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x174422a80>>: item=<<UINavigationItem: 0x1703c6900>: title:'Accounts'> title=Accounts>
   |    |    |    |    |    |    | <UILabel: 0x102b1a660; frame = (0 3; 75.3333 21.3333); text = 'Accounts'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x17488cda0>>
   |    |    |    |    |    | <UINavigationButton: 0x102a80b40; frame = (9 6; 48 30); opaque = NO; tintColor = UIExtendedSRGBColorSpace 0.313725 0.52549 0.764706 1; layer = <CALayer: 0x174830340>>
   |    |    |    |    |    |    | <UIImageView: 0x102b66cd0; frame = (11 2; 26 26); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x170c20bc0>> - (null)
   |    |    |    |    |    | <_UINavigationBarBackIndicatorView: 0x102ab00f0; frame = (12 11.6667; 13 21); alpha = 0; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x17422ad20>> - Back

【问题讨论】:

为什么你有两次[self.navigationController pushViewController:viewController animated:YES]; 糟糕。错字。我会解决的。 您能否更具体地说明您将上述代码放在何处?我最初的想法是你创建RCTView的对象和从JS端接收调用的对象不一样。 它们是一样的。它们都在同一个 UIViewController 中。 我也遇到了同样的问题,你最后解决了吗? @帐篷制作 【参考方案1】:

您是否尝试过从 rootViewController 展示您的 vc ?

UIViewController *rootVC = [[[UIApplication sharedApplication] window] rootViewController];
[rootVC presentViewController:viewController animated:YES completion: nil];

更新:

关于您的视图层次结构,我可以建议使用一些丑陋的内省来推送:

UIViewController *rootVC = [[[UIApplication sharedApplication] window] rootViewController];
if ([rootVC isKindOfClass:[MMDrawerController class]]) 
    MMDrawerController *drawer = (MMDrawerController *)rootVC;
    UIViewController *realRootVC = drawer.centerViewController;
    if (realRootVC != nil) 
        if (realRootVC.navigationController != nil) 
            [realRootVC.navigationController presentViewController:viewController animated:YES completion: nil];
         else if ([realRootVC isKindOfClass:[UINavigationController class]]) 
            UINavigationController *nv = (UINavigationController *)realRootVC;
            [nv presentViewController:viewController animated:YES completion: nil];
        
    

【讨论】:

是的,这不起作用,因为我的导航层次结构如何工作。 rootViewController 是一个菜单抽屉。 您能否在推送时提供您的视图层次结构? (添加断点并在控制台执行po [[UIWindow keyWindow] recursiveDescription] 好的,我将它添加到问题中。我删除了一些子视图,因为它们不包含有价值的信息,只是父视图的单元格或子视图。

以上是关于UINavigationController 在 RCT_EXPORT_METHOD 中为零(React Native)的主要内容,如果未能解决你的问题,请参考以下文章

在 UINavigationController 内的 UITabBarcontroller 中添加 UINavigationController?

从嵌入在 UINavigationController 中的一个视图控制器到另一个 UINavigationController

(Swift) 在嵌套在 Main UINavigationController 中的 UINavigationController 和 UITabController 之间切换

关闭 UINavigationController 并呈现另一个 UINavigationController

带有主 UINavigationController 和详细 UINavigationController 的 UISplitViewcontroller

UINavigationController 标题和按钮