WKWebView dismiss its entire view controller when presented modally

Originator:matax87
Number:rdar://34547298 Date Originated:09/20/2017
Status:Open Resolved:
Product:WebKit Product Version:iOS 11.0
Classification:Bug Reproducible:Always
 
Area:
WebKit

Summary:
On iOS 11.0, "WKWebView"s which are presented modally will dismiss their view controller when a callout is dismissed (both "UIPopoverPresentationController" and "UIAlertController").

Steps to Reproduce:
1. Create a view controller containing a "WKWebView" loading some URL
2. Present modally the view controller of the previous step
3. Tap and hold on a link in the web page to present the callout (popover or alert)
4. Dismiss the callout (popover or alert)

or you can download my sample project (https://github.com/matteomatassoni/ModalWebViewiOS11Bug), run it and then follow step 3 and 4

Expected Results:
Dismiss of callout of step 3 and 4

Actual Results:
Dismiss of presented view controller of step 2

Version/Build:
iOS 11.0

Configuration:
Any

Comments

Same problem

Wow what an annoying bug. I would guess when they added the force touch support (which opens the popover / link preview) they added the dismiss call without thinking that if it was just the action sheet (which you get by just holding down on the link for a moment without pressing enough to activate force touch) it would mess up the view controller that presented the action sheet.

Note there's an allowsLinkPreview property on WKWebView which can turn off the force touch popover but it still allows the regular holding down action sheet which seems to be the real probelm. Anyhow, I like that functionality but the unnecessary dismiss is so frustrating.

Temp code solution

Extended the presenting view controller, a UINavigationController in this particular case, and overrode the dismissViewControllerAnimated:completion: method to track a weak reference to the presented controller being dismissed. The weak reference to the dismissed controller guards the second call and prevents the modal from being dismissed.

Should Apple change the behavior in the future this workaround will no longer be needed, but should not cause an issue.

- (void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)())completion {
    if (self.presentedViewController) {
        self.lastPresentedController = self.presentedViewController;
        [self.presentedViewController dismissViewControllerAnimated:YES completion:^{
            self.lastPresentedController = nil;
        }];
    } else if (!self.lastPresentedController) {
        [super dismissViewControllerAnimated:flag completion:completion];
    }
}
By rich.ball at May 25, 2018, 2:45 p.m. (reply...)

Temp solution

We currently fix this be disabling callout on iOS 11 by injected javascript and CSS

WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init]; if (!self.calloutEnabled) { // Javascript that disables callout by inserting the HTML viewport meta tag into NSString *source = @"var style = document.createElement('style'); style.type = 'text/css'; style.innerText = '*:not(input):not(textarea) { -webkit-user-select: none; -webkit-touch-callout: none; }'; var head = document.getElementsByTagName('head')[0]; head.appendChild(style);"; WKUserScript *script = [[WKUserScript alloc] initWithSource:source injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];

    // Create the user content controller and add the script to it
    WKUserContentController *userContentController = [[WKUserContentController alloc] init];
    [userContentController addUserScript:script];

    // Add the user content controller to the configuration
    configuration.userContentController = userContentController;
}

// Create the web view with the configuration
self.webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration];

Encountered this problem as well. Hope we can have a fix soon.

Any news on this one?

Not yet


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!