当 WKWebView 尝试呈现 WKActionSheet 时,长按会导致 error/warning
Long press leads to an error/warning when WKWebView tries to present a WKActionSheet
我的视图层次结构如下所示:
- (root) PRSBaseViewController - 一个 UIViewController 子类 - 有子视图控制器
- (呈现) PRSModalWebViewController - UINavigationController 子类
- (pushed, animated:NO) PRSWebViewController - UIViewController 子类 - WKWebView 是一个子视图。
当我尝试长按 WebView 中的 link 时,出现错误:
Warning: Attempt to present <WKActionSheet: 0x127520d10> on <PRSBaseViewController: 0x1275117f0> whose view is not in the window hierarchy!
不是使用 presentViewController:animated:completion
呈现导航,而是使用 addChildViewController:
舞蹈将视图控制器添加到层次结构中。我没有得到任何错误,这很奇怪。
有谁知道可能导致视图层次结构问题的原因吗?
更新:我做了一个Gist of all my classes
我遇到过类似的行为 - 但也没有弄清楚这种情况是如何发生的或为什么会发生。
这是我的解决方法。由于 WKWebView 正在调用我的 RootViewController,我通过覆盖 RootViewController 的 presentViewController:animated:completion 来处理这个问题:- 如果 RootViewController 已经有一个 presentedViewController,那么它会将消息转发到该控制器。它似乎解决了警告消息,并在模态视图中使用 WKWebView 时为我提供了长按菜单。
- (void)presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion {
// Unsure why WKWebView calls this controller - instead of it's own parent controller
if (self.presentedViewController) {
[self.presentedViewController presentViewController:viewControllerToPresent animated:flag completion:completion];
} else {
[super presentViewController:viewControllerToPresent animated:flag completion:completion];
}
}
或在swift:
override func presentViewController(viewControllerToPresent: UIViewController, animated flag: Bool, completion: (() -> Void)?) {
if presentedViewController != nil {
// Unsure why WKWebView calls this controller - instead of it's own parent controller
presentedViewController?.presentViewController(viewControllerToPresent, animated: flag, completion: completion)
} else {
super.presentViewController(viewControllerToPresent, animated: flag, completion: completion)
}
}
我们也在 PSPDFKit 中看到了这个问题,在调查了 UIKit 程序集和 WKWebView
来源之后,我们发现了一个仍然很糟糕但没有侵入性的解决方法。
主要策略是有选择地及时应用解决方法 - 然后再次清理。您可以在这里阅读源代码:
https://gist.github.com/steipete/b00fc02aa9f1c66c11d0f996b1ba1265
请欺骗 rdar://26295020,这样这有望在 iOS 10 时得到及时修复。(该错误自 iOS 8 以来就存在,并首次在 iOS 上报告8b5.)
我的视图层次结构如下所示:
- (root) PRSBaseViewController - 一个 UIViewController 子类 - 有子视图控制器
- (呈现) PRSModalWebViewController - UINavigationController 子类
- (pushed, animated:NO) PRSWebViewController - UIViewController 子类 - WKWebView 是一个子视图。
- (呈现) PRSModalWebViewController - UINavigationController 子类
当我尝试长按 WebView 中的 link 时,出现错误:
Warning: Attempt to present <WKActionSheet: 0x127520d10> on <PRSBaseViewController: 0x1275117f0> whose view is not in the window hierarchy!
不是使用 presentViewController:animated:completion
呈现导航,而是使用 addChildViewController:
舞蹈将视图控制器添加到层次结构中。我没有得到任何错误,这很奇怪。
有谁知道可能导致视图层次结构问题的原因吗?
更新:我做了一个Gist of all my classes
我遇到过类似的行为 - 但也没有弄清楚这种情况是如何发生的或为什么会发生。
这是我的解决方法。由于 WKWebView 正在调用我的 RootViewController,我通过覆盖 RootViewController 的 presentViewController:animated:completion 来处理这个问题:- 如果 RootViewController 已经有一个 presentedViewController,那么它会将消息转发到该控制器。它似乎解决了警告消息,并在模态视图中使用 WKWebView 时为我提供了长按菜单。
- (void)presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion {
// Unsure why WKWebView calls this controller - instead of it's own parent controller
if (self.presentedViewController) {
[self.presentedViewController presentViewController:viewControllerToPresent animated:flag completion:completion];
} else {
[super presentViewController:viewControllerToPresent animated:flag completion:completion];
}
}
或在swift:
override func presentViewController(viewControllerToPresent: UIViewController, animated flag: Bool, completion: (() -> Void)?) {
if presentedViewController != nil {
// Unsure why WKWebView calls this controller - instead of it's own parent controller
presentedViewController?.presentViewController(viewControllerToPresent, animated: flag, completion: completion)
} else {
super.presentViewController(viewControllerToPresent, animated: flag, completion: completion)
}
}
我们也在 PSPDFKit 中看到了这个问题,在调查了 UIKit 程序集和 WKWebView
来源之后,我们发现了一个仍然很糟糕但没有侵入性的解决方法。
主要策略是有选择地及时应用解决方法 - 然后再次清理。您可以在这里阅读源代码:
https://gist.github.com/steipete/b00fc02aa9f1c66c11d0f996b1ba1265
请欺骗 rdar://26295020,这样这有望在 iOS 10 时得到及时修复。(该错误自 iOS 8 以来就存在,并首次在 iOS 上报告8b5.)