UIWebView throwing exception for [WebActionDisabli

2019-03-07 20:10发布

问题:

When running against iOS 8, I began to see the following exception coming from the deep bowels of UIWebView:

[WebActionDisablingCALayerDelegate setBeingRemoved:]: unrecognized selector sent to instance 0x167ee900

* WebKit discarded an uncaught exception in the webView:willRemoveScrollingLayer:withContentsLayer:forNode: delegate: -[WebActionDisablingCALayerDelegate setBeingRemoved:

This is happening when I change some constraints on my UIWebView and then call:

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

(This is so that the webview's content is re-rendered to fit its width correctly).

Luckily the exception is discarded, so the app isn't crashing. Why is this happening, and is there any way to prevent it?

回答1:

I found that by adding "-webkit-transform: translateZ(0px);" to the scrollable content (I have a div inside my scrollable container), it fixed the issue for me. Hope this helps.



回答2:

Not sure if this is your case, but I also started seeing this problem on iOS 8 and we tracked it down to the usage of the following CSS property on an iframe:

-webkit-overflow-scrolling: touch;

After we removed it, we no longer had those error messages.

Note: in my case, it didn't happen in response to changing any constraints, but rather it happened while we were navigating through the HTML.



回答3:

As none of the answers given could help me I had to resolve this issue with help of Objective-C runtime.

First I've provided a simple function:

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

Then these two lines:

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

And it works.



回答4:

Use WKWebView instead of UIWebView. (it was first included in iOS 8). I've tried it, and seems that it hasn't got this bug. Also, it may improve the performance compared with it predecessor. Seems likely that Apple will make the de-facto standard in the near future, if not now. It has interfaces and delegates somewhat similar to UIWebView. Definitively worth a try.

If you are targeting pre-iOS 8, you can implement fallback procedures to load either UIWebView or WKWebView, here you are an out-of-the-box implementation



回答5:

In my case the problem was a <table> inside of iframe content. The table width was greater than the iframe width defined via CSS. The iframe scrolling was off, and the table has stretched the iframe to the minimum calculated width of the table. Other side effect: content of the iframe was not completely visible (cut off on the right side).

|--- 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 ------------------|

Removing the table form iframe content has fixed the problem.



回答6:

As @André Morujão answered, removing -webkit-overflow-scrolling:touch; from the scrolling element stops the exception. But I found that the exception was only happening when I added display:none css to the scrolling element.

Edit: I was able to continue using display:none to hide my scrolling element by putting -webkit-overflow-scrolling:touch; inside of its own class .scroll and using jquery to add and remove that class from my scrolling element before and after hiding it:

<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>