React Native Push而不是Present native iOS视图

时间:2017-07-19 17:54:47

标签: swift react-native

我想在反应原生应用程序中显示本机视图控制器(ABPersonViewController)。

我可以展示视图,但我不能推动视图。此代码片段可以工作并显示视图,但我的应用程序没有后退按钮:

let personViewController = ABPersonViewController()
let rootViewController:UIViewController? 
        = UIApplication.shared.delegate?.window??.rootViewController!

personViewController.displayedPerson = record!

// this works
rootViewController!.present(personViewController, animated: true)

如果我尝试推送视图而不是呈现视图,则没有任何反应因为navigationController为nil:

if (rootViewController!.navigationController != nil) {
      rootViewController!.navigationController!.pushViewController(personViewController, animated: true)
}

如何在本机iOS响应中推送本机视图?

在React原生android中,可以使用自定义模块中的代码轻松完成视图联系人:

final Activity activity = getCurrentActivity();
Intent contactIntent = new Intent(Intent.ACTION_VIEW);
Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_URI, id);

contactIntent.setData(uri);
activity.startActivity(contactIntent);

我希望在原生iOS的反应中这很容易!

我尝试了@ Artal的iOS解决方案,它可以解决问题。

我分配了一个UINavigationController,它使用现有的RN UIViewController作为其根,并将其设置为窗口的rootViewController。这是代码:

UIViewController *rootViewController = [UIViewController new];
UINavigationController *navigationController = [[UINavigationController alloc]initWithRootViewController:rootViewController];

navigationController.navigationBarHidden = YES;   
rootViewController.view = rootView;
self.window.rootViewController = navigationController;

在我的swift代码中,我将rootViewController转换为UINavigationController,将isNavigationBarHidden设置为false并推送personViewController

let navigationController:UINavigationController = rootViewController as! UINavigationController;

DispatchQueue.main.async {
   navigationController.isNavigationBarHidden = false;
   navigationController.pushViewController(personViewController, animated: true)

}

当我重新使用UINavigationController ShouldPopOnBackButton以便在返回RN时将navigationBarHidden设置为true时出现了问题。我按照https://stackoverflow.com/a/19132881/826435

中的方法进行了操作
@implementation UINavigationController (ShouldPopOnBackButton)

- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item {
  if([self.viewControllers count] < [navigationBar.items count]) {
    return YES;
  }

  dispatch_async(dispatch_get_main_queue(), ^{
    self.navigationBarHidden = YES;
    [self popViewControllerAnimated:YES];
  });

  return NO;
}

@end

调用AftershouldPopItem,恢复RN视图,但随后在模拟器上运行时对所有输入字段禁用RN键盘;它在设备上工作正常。

为什么模拟器上的RN键盘被禁用了?

詹姆斯

3 个答案:

答案 0 :(得分:0)

您无法推送视图控制器,因为RN应用的默认rootViewControllerUIViewController而不是UINavigationController,这也是您看到{{1}的原因}}

如果您想使用本机导航堆栈并推送另一个原生屏幕,您有两个选择:

  1. 使用RNN等原生导航解决方案。这种方法的缺点是它需要改变你当前处理导航的方式。 注意:虽然RN附带了一个开箱即用的原生导航解决方案(NavigatorIOS),但它不允许您推送其他原生屏幕。你可以通过访问一些私有财产来破解它,但我不确定你是否想去那里。
  2. nil中更改应用的根目录。您可以分配将使用现有RN AppDelegate作为其根目录的UINavigationController,并将其设置为窗口的UIViewController。请注意,此类更改可能会对您的应用产生其他影响;例如:您将获得rootViewController原生导航栏以及可能的其他一些副作用。

答案 1 :(得分:0)

@ Artal建议的解决方案(2)可以在设备上运行,但在模拟器上,键盘在从原生视图返回后被禁用。

答案 2 :(得分:0)

也许您可以将Objective-C navigationController传递给Swift方法。

(UINavigationController *)[UIApplication sharedApplication].keyWindow.rootViewController可以在React Native中转换为navigationController

但是

UIApplication.shared.keyWindow?.rootViewController as? UINavigationController