长按在WKWebView中弹出WKActionSheet时导致错误/警告。

8

我的视图层次结构如下:

  • (根) PRSBaseViewController - UIViewController子类 - 有子视图控制器
    • (呈现) PRSModalWebViewController - UINavigationController子类
      • (不带动画推送) PRSWebViewController - UIViewController子类 - WKWebView是其子视图。

当我尝试在WebView上长按链接时,会出现以下错误:

警告:试图将<WKActionSheet: 0x127520d10>显示在未在窗口层次结构中的<PRSBaseViewController: 0x1275117f0>上!

不要使用presentViewController:animated:completion呈现导航,而是使用addChildViewController:添加到视图控制器层次结构。这样做我就没有错误了,这很奇怪。

有人知道是什么原因导致了视图层次结构问题吗?

更新: 我创建了一个Gist文件包含了我所有的类


2
@matt 我并不是想要压制分享面板,它们是在违背我的意愿被压制的。我不想要的行为就是他所问的答案。 - Shawn Throop
那么RootViewController到底是什么?你说你已经放了一份你的类的代码片段,但在其中没有RootViewController。你能展示一下RootViewController如何进入视图层级结构,并且如何获取它的WKWebView子视图吗?(在nib中无法获取到它,因为对象库中没有WKWebView;你必须通过代码实现这一切。) - matt
你似乎想要使用PRSWebViewController作为UINavigationController的根视图控制器,但是一些RootViewController不知怎么悄悄地出现了。 - matt
但错误信息非常明确地表明这是一个RootViewController。这就是我的观点。如果您之前使用过RootViewController,那么我的猜测是您仍然拥有旧版本的故事板在您的中间构建中。我建议您首先清除缓存,就像我在这里解释的那样:https://dev59.com/cW025IYBdhLWcg3w7qjL#6247073 - matt
1
这个 bug 的出现是因为 WebKit 错误地尝试在 [view.window rootViewController] 上呈现 WKActionSheet来源)。但是,如果根视图控制器已经在呈现某些内容,则这是错误的。 - Lily Ballard
显示剩余5条评论
2个回答

13

我也遇到过类似的行为,也没有弄清楚为什么会发生。

这是我的解决方法。由于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)
    }
}

1
这正是我所做的,只是忘记回答自己的问题了。 - Shawn Throop
这个修复是显示 actionsheet 还是禁止它?我想在我的应用程序中看到 actionsheet,以便我可以执行一些操作。 - Alok C
它可以工作!太棒了!将Todd的代码添加到您的控制器中,就像警告详细信息中的“<PRSBaseViewController>”一样。 - Baryon Lee
这是我实施的解决方法。当我开始看到崩溃报告时,这个问题在我的应用程序中变得明显起来。如果WKWebView被关闭并且设备随后旋转,则该问题会表现为异常并导致应用程序崩溃。 - isaac

4
我们在PSPDFKit中也遇到了这个问题,在调查了UIKit程序集和WKWebView源代码后,我们找到了一个解决方法,虽然仍然很糟糕,但不会有影响。
主要策略是有选择地应用一种解决方法,然后再清理。您可以在此处阅读源代码:

https://gist.github.com/steipete/b00fc02aa9f1c66c11d0f996b1ba1265

请复制rdar://26295020,以便在iOS 10发布前解决这个问题。(该漏洞存在自iOS 8以来,并首次在iOS 8b5上报告。)


1
这也适用于任意长的未知呈现视图控制器链,这是因为我们正在开发一个框架,所以无法控制应用程序中的所有视图控制器。 - Douglas Hill

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接