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>