React Native Push 而不是 Present 本机 iOS 视图
Posted
技术标签:
【中文标题】React Native Push 而不是 Present 本机 iOS 视图【英文标题】:React Native Push rather than Present native iOS view 【发布时间】:2017-07-19 17:54:46 【问题描述】:我想在 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)
如何在 react native ios 中推送原生视图?
在 React native 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);
我希望 React Native 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;
在我的快速代码中,我将 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://***.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;
@结束
在调用之后,RN 视图恢复,但随后在模拟器上运行时,所有输入字段的 RN 键盘都被禁用;不过它在设备上运行良好。
知道为什么模拟器上的 RN 键盘被禁用了吗?
詹姆斯
【问题讨论】:
据我所知,您所做的似乎无法直接通过 Swift-React 桥接代码完成。参考这个,也许你会找到解决办法。 github.com/facebook/react-native/issues/1148 。此外,请熟悉 iOS 中的自定义过渡,这通常是获得您可能想要的独特过渡的最简单方法。 raywenderlich.com/146692/… 出于好奇,您的第一个代码块是在 AppDelegate 中吗?.. 没有代码在一个单独的 swift 模块中,该模块通过 react native bridge 调用。感谢其他参考;我去看看。 【参考方案1】:您无法推送视图控制器,因为 RN 应用程序的默认 rootViewController
是 UIViewController
而不是 UINavigationController
,这也是您看到它是 nil
的原因。
如果您想使用原生导航堆栈并推送另一个原生屏幕,您有两种选择:
-
使用原生导航解决方案,例如RNN。这种方法的缺点是它需要完全改变您当前处理导航的方式。 注意:虽然 RN 带有一个开箱即用的原生导航解决方案 (NavigatorIOS),但它不允许您推送其他原生屏幕。您也许可以通过访问一些私有属性来破解它,但我不确定您是否想去那里。
在
AppDelegate
中更改应用的根目录。您可以分配一个UINavigationController
,它将使用现有的RN UIViewController
作为其根,并将其设置为您窗口的rootViewController
。请注意,这种更改可能会对您的应用产生其他影响;例如:您将获得 UINavigationController
原生导航栏和可能的其他一些副作用。
【讨论】:
On (1) 感谢您提供响应本机导航的链接(它取代了 github.com/facebook/react-native/issues/1148 中提到的 react 本机控制器)并澄清您无法推送视图。 (2)的任何例子?我也想过使用 React Native Linking,但在 iOS 上没有 addressbook://ABRecrord uniqueId 的等价物。【参考方案2】:也许你可以将 Objective-C navigationController 传递给 Swift 方法。
(UINavigationController *)[UIApplication sharedApplication].keyWindow.rootViewController
可以在 React Native 中转换为 navigationController
。
但是
UIApplication.shared.keyWindow?.rootViewController as? UINavigationController
【讨论】:
【参考方案3】:@Artal 建议的解决方案 (2) 确实适用于设备,但在模拟器上,键盘在从本机视图返回后被禁用。
【讨论】:
你能告诉我如何“分配一个 UINavigationController,它将使用现有的 RN UIViewController 作为它的根,并将它设置为你窗口的 rootViewController。” (1)首先更改AppDelegate.m并替换“UIViewController *rootViewController = [UIViewController new]; rootViewController.view = rootView; self.window.rootViewController = rootViewController;”使用“UIViewController *rootViewController = [UIViewController new]; UINavigationController *navigationController = [[UINavigationController alloc]initWithRootViewController:rootViewController]; navigationController.navigationBarHidden = YES; rootViewController.view = rootView; self.window.rootViewController = navigationController;” (2) 获取 routeViewController 并推送视图:“让 navigationController:UINavigationController = rootViewController as! UINavigationController; DispatchQueue.main.async navigationController.isNavigationBarHidden = false; navigationController.pushViewController(personViewController, animated : 真) "以上是关于React Native Push 而不是 Present 本机 iOS 视图的主要内容,如果未能解决你的问题,请参考以下文章
React-native:使用 zo0r/react-native-push-notification 显示前台通知,例如后台通知
React Native Push Notifications 在 Android 中不起作用,但在 iOS 上运行良好
重复本地通知在 react-native-push-notification 中不起作用
React Native错误:undefined不是对象(评估'_this2.props.navigation.navigate')