【问题标题】:Can't push a native view controller from a react-native click无法通过本机点击推送本机视图控制器
【发布时间】:2015-06-18 07:23:39
【问题描述】:

我们正在将 react native 添加到现有应用程序中,并且无法将原生视图控制器推送到另一个包含 react native 视图的原生视图控制器之上。

主视图控制器的 viewDidLoad 如下所示:

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

react 视图是一个 ListView,其中 TouchableHighlight 的 onPress 被导出到同一视图控制器上的此方法:

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];
        });

}

该方法确实被调用,但 SNKProductViewController 从未被推送到屏幕上(没有日志消息)。我还尝试以模态方式呈现视图控制器,并收到以下控制台消息:

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

任何帮助将不胜感激,非常感谢!

【问题讨论】:

  • 既然你使用self来推送视图控制器,你能确认RCT_EXPORT_METHOD和viewDidLoad在同一个类(即你的MainViewController)吗?否则获取 topController 并推送 SNKProductViewController。 UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController; while (topController.presentedViewController) { topController = topController.presentedViewController; } [topController pushViewController:vc 动画:YES];
  • 不相关,但设置视图的正确方法是使用 -(void)loadView 方法而不是 viewDidLoad。

标签: ios react-native


【解决方案1】:

在 Reac-Native 调用 RCT_EXPORT_MODULE 宏之后,创建了这个模块的新实例。在调用RCT_EXPORT_METHOD 方法之后,该方法从另一个模块实例调用。为了解决这个问题,我只找到了一个解决方案。在从 js 调用的方法位置中搜索我在 Hierarchy 控制器中的 ViewController:

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];
    });
}

在这个例子中,我需要的控制器有一个位置 window&gt;rootViewController&gt;authViewController

UPD

this i found 一些解决方案我们如何获取当前的 ViewController

【讨论】:

  • 在上面的代码中,你将 AuthorizationView 设置为你的根视图控制器???
  • @Ramakrishna 没关系,如果我的 AuthorizationView 是 NavigationController 中的第一个 VC,它必须在 Root 中,如果不是的话)
  • 如何在我使用推送代码的视图控制器中设置 RCTRootView。当我推送到另一个视图控制器时,每次都需要设置 RCTRootView 吗?你能解释清楚吗。我需要它。
  • 如何在应用程序委托中为此使用导航控制器,请帮助我。
  • 这是另一个话题的问题。但在我的示例中,它是本机实现自定义组件。您不能编码推送本机代码。它必须在您的生产版本中编译。你不需要在工作中实现这个。 RN 尝试从原生细微差别的围栏开发人员。
【解决方案2】:

我认为您应该像这样更改主视图控制器中的 -viewDidLoad 方法:

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

也就是说,不要将RCTRootView设置为'self.view';将其设为子视图。

【讨论】:

    猜你喜欢
    • 2020-05-24
    • 1970-01-01
    • 1970-01-01
    • 2011-01-27
    • 2016-08-10
    • 1970-01-01
    • 1970-01-01
    • 2020-04-01
    • 2012-07-07
    相关资源
    最近更新 更多