React Native Push而不是当前的本机iOS视图

问题描述:

我想在反应本机应用程序中显示本地视图控制器(ABPersonViewController)。React Native Push而不是当前的本机iOS视图

我可以呈现视图,但我不能推视图。这段代码工作,并提出了看法,但没有返回按钮,我的应用程序:

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

personViewController.displayedPerson = record! 

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

如果我试图推动的观点,而不是目前的观点,什么都不会发生,因为navigationController是零:

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

如何在反应原生iOS中推送原生视图?

在阵营原生的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键盘被禁用?

詹姆斯

+0

从我能找到的,看来你正在做的事不能通过Swift-React桥接代码直接完成。参考这个,也许你会找到一个解决方案。 https://github.com/facebook/react-native/issues/1148。另外,请注意熟悉iOS中的自定义转换,通常是获得您可能想要的独特转换的最简单方法。 https://www.raywenderlich.com/146692/ios-animation-tutorial-custom-view-controller-presentation-transitions-2 – murphguy

+0

出于好奇,是你的第一个代码块在AppDelegate?.. – murphguy

+0

没有代码是在一个独立的swift模块,通过反应本地桥被调用。感谢您的其他参考资料;我会看看。 – jmc42

你不能把一个视图控制器,因为RN应用程序的默认rootViewControllerUIViewController而不是UINavigationController,这也是为什么你看到它的nil

如果要使用本机导航堆栈和推另一本机屏幕有两个选项:

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

关于(1)感谢链接以回应原生导航(取代https://github.com/facebook/react-native/issues/1148中提到的原生控制器),并澄清您无法推送视图。 (2)的任何例子?我也想过使用React Native Linking,但在iOS上没有地址簿的相应功能:// {ABRecrord uniqueId}。 – jmc42

@Artal建议的解决方案(2)可以在设备上工作,但在模拟器上,从本机视图返回后禁用键盘。

+0

你能告诉我如何“分配一个UINavigationController,它将使用现有的RN UIViewController作为它的根,并将它设置为你窗口的rootViewController。” – nik

+0

(1)首先更改AppDelegate.m并替换“UIViewController * rootViewController = [UIViewController new]; rootViewController.view = rootView; self.window.rootViewController = rootViewController;”用“的UIViewController * RootViewController的= [UIViewController中新]; 的UINavigationController * navigationController = [[UINavigationController的页头] initWithRootViewController:RootViewController的]; navigationController.navigationBarHidden = YES; rootViewController.view = rootView; self.window.rootViewController = navigationController; “ – jmc42

+0

(2)获取routeViewController并且因此推观点:“让navigationController:的UINavigationController = RootViewController的作为的UINavigationController; DispatchQueue.main.async { navigationController.isNavigationBarHidden = FALSE; navigationController.pushViewController(personViewController,动画:真)! }“ – jmc42