模块应该在主线程中显示 modal/UIViewController 但它不会立即工作

Modul should show modal/UIViewController in main thread but it doesnt work without delay

我试图在 Swift 模块的 React 本机应用程序中呈现 UIViewController 我是这样呈现的

  let screen = UIApplication.shared.windows.filter {[=11=].isKeyWindow}.first
  screen?.rootViewController?.present(payController!, animated: true, completion: nil);
  

我得到这个错误: UIApplication.windows must be used from main thread only

好的,我必须将它添加到我的主题中

  DispatchQueue.main.async {
    let screen = UIApplication.shared.windows.filter {[=12=].isKeyWindow}.first
    screen?.rootViewController?.present(payController!, animated: true, completion: nil);
  }

当我以较小的延迟调用此函数时它工作正常

setTimeout(() => {
  showMyWiew();
}, 500);

或者这样延迟到swift

  DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
    let screen = UIApplication.shared.windows.filter {[=14=].isKeyWindow}.first
    screen?.rootViewController?.present(payController!, animated: true, completion: nil);
  }

但如果我删除延迟,则不会显示此模式。但它应该在那里。我在登录 swift 中看到了这一点,这证实了我的理论:

[Presentation] Attempt to present <PKAddPaymentPassViewController: 0x103d6b2e0> on <UIViewController: 0x103c25480> (from <UIViewController: 0x103c25480>) which is already presenting <RCTModalHostViewController: 0x10e21df40>.

PKAddPaymentPassViewController 是我的 UIViewController

我不知道如何解决这个问题...

更新

根据第一条评论,我这样做了

  DispatchQueue.main.async {
    let screen = UIApplication.shared.windows.filter {[=16=].isKeyWindow}.first
    let controller = screen?.rootViewController?.presentedViewController;
    if controller == nil {
      screen?.rootViewController?.present(payController!, animated: true, completion: nil);
    } else {
      screen?.rootViewController?.presentedViewController?.present(payController!, animated: true, completion: nil)
    }

  }

好消息是模式会显示但立即关闭我看到打开效果然后关闭效果...

解决方案

  1. 全部在更新部分
  2. 重构RN代码 原来在这个new之前还有open another modal。在我打开新模式之前旧模式没有关闭...所以我更快地关闭旧模式然后我显示新模式并且一切都很好

那是因为在那一刻 screen?.rootViewController 似乎已经呈现另一个 ViewController (RCTModalHostViewController)。已经呈现一些 VC 的 VC 不能 呈现另一个 VC。您可以做的是在 VC 上调用 present,此时根 ViewController 正在呈现:screen?.rootViewController.presentedViewController?.present(...)。 (展示一个展示的 ViewController 确实有效。展示一个展示另一个 VC 的 VC 没有效果。)

如果这样做,您还应确保 presentedViewController 已实际设置,而不是 nil。如果它是零,你可以像之前一样在 rootViewController 上调用 present。