模块应该在主线程中显示 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)
}
}
好消息是模式会显示但立即关闭我看到打开效果然后关闭效果...
解决方案
- 全部在更新部分
- 重构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。
我试图在 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)
}
}
好消息是模式会显示但立即关闭我看到打开效果然后关闭效果...
解决方案
- 全部在更新部分
- 重构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。