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 应用程序的默认 rootViewControllerUIViewController 而不是 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 中的函数

React-native:使用 zo0r/react-native-push-notification 显示前台通知,例如后台通知

React Native Push Notifications 在 Android 中不起作用,但在 iOS 上运行良好

重复本地通知在 react-native-push-notification 中不起作用

React Native错误:undefined不是对象(评估'_this2.props.navigation.navigate')

React Native Push Notification - react-native-fcm - ios无法构建