UIWebView为抛出exception

在iOS 8下运行时,我开始看到以下exception来自UIWebView的深层次:

[WebActionDisablingCALayerDelegate setBeingRemoved:]:无法识别的select器发送到实例0x167ee900

* WebKit在webView中放弃了未捕获的exception:willRemoveScrollingLayer:withContentsLayer:forNode:delegate: – [WebActionDisablingCALayerDelegate setBeingRemoved:

发生这种情况时,我改变了我的UIWebView一些约束,然后调用:

  self.webViewWidthConstraints.constant = newWidth; [self.webView setNeedsLayout]; [self.webView layoutIfNeeded]; 

(这是为了使webview的内容重新渲染,以适应其宽度)。

幸运的是,这个例外被丢弃,所以应用程序不会崩溃。 为什么会发生这种情况,有什么办法可以防止它呢?

我发现通过添加“-webkit-transform:translateZ(0px);” 到可滚动的内容(我的可滚动容器内有一个div),它解决了我的问题。 希望这可以帮助。

不知道这是否是你的情况,但我也开始在iOS 8上看到这个问题,我们跟踪到在iframe上使用下面的CSS属性:

 -webkit-overflow-scrolling: touch; 

我们删除后,我们不再有这些错误消息。

注意:在我的情况下,它不是为了响应改变任何约束而发生的,而是在我们浏览HTML时发生的。

由于没有给出的答案可以帮助我,我不得不借助Objective-C运行时来解决这个问题。

首先我提供了一个简单的function:

 id setBeingRemoved(id self, SEL selector, ...) { return nil; } 

那么这两行:

  Class class = NSClassFromString(@"WebActionDisablingCALayerDelegate"); class_addMethod(class, @selector(setBeingRemoved:), setBeingRemoved, NULL); 

它工作。

使用WKWebView而不是UIWebView 。 (这是第一次被包含在iOS 8中)。 我试过了,似乎没有得到这个错误。 此外,它可能会提高性能相比,它的前身。 似乎苹果可能会在不久的将来成为事实上的标准,如果不是现在。 它的接口和委托有点类似于UIWebView。 肯定值得一试。

如果您的目标是iOS 8之前的版本,则可以实施回退过程来加载UIWebView或WKWebView, 这里您是一个开箱即用的实现

在我的情况下,问题是iframe内容的<table>。 表格宽度大于通过CSS定义的iframe宽度。 iframe滚动已closures,并且表格已将iframe拉伸至表格的最小计算宽度。 其他副作用:iframe的内容不完全可见(在右侧切断)。

 |--- Available viewport width -------------| |--- defined and estimated iframe width ---| |--- table width in the iframe content > than defined iframe width ---| |--- iframe stretched to the calculated table width ------------------| 

删除表格的iframe内容已经解决了这个问题。

正如@AndréMorujão回答的,删除了-webkit-overflow-scrolling:touch; 从滚动元素停止exception。 但我发现,只有当我添加display:none滚动元素display:none CSS的exception。

编辑:我能继续使用display:none通过把-webkit-overflow-scrolling:touch;隐藏我的滚动元素-webkit-overflow-scrolling:touch; 在其自己的类.scroll和使用jquery来添加和删除我的滚动元素之前和之后隐藏它:

 <style> .scroll { -webkit-overflow-scrolling:touch; } </style> <script> function hide() { $('#scrolling_element).removeClass('scroll'); $('#scrolling_element).css('display', 'none'); } function show() { $('#scrolling_element).css('display', 'block'); $('#scrolling_element).addClass('scroll'); } </script>