WKWebview: Disable interaction and clicks on links
Asked Answered
C

6

11

Is there a way to disable interactions on a webview? So that the user can not go any further than the webview that is loaded?

EDIT: Disabling UserInteractions is not a solution because the website still has to be scrollable.

Companionable answered 12/4, 2017 at 10:26 Comment(2)
you can implement delegate methods of webview.Prehistoric
Possible duplicate of Restricting user interaction in UIWebViewClough
C
9

Implement the WKNavigationDelegate protocol:

@interface ViewController () <WKNavigationDelegate>

Set your WKWebView's navigationDelegate property:

self.wkWebView.navigationDelegate = self;

Then implement the policy for the URL(s) that you want to restrict:

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {

    if ([navigationAction.request.URL.absoluteString containsString:@"somedomain.com/url/here"]) {
        decisionHandler(WKNavigationActionPolicyAllow);
    }
    else {
        decisionHandler(WKNavigationActionPolicyCancel);
    }
}
Cheap answered 12/4, 2017 at 10:39 Comment(2)
The problem here is when i got a url like google.com i.e and it should not open google.com/"something" it does not work with containsString but i can not diasable userInteractions because of scrolling.Companionable
You can use isEqualToString or some other comparison in that case.Cheap
A
9

The WKNavigationDelegate solution only prevents the user from following links. I also have form controls that I want to prevent interaction with, while still allowing the page to be scrolled. Eventually I figured out that this could be achieved by disabling the subviews of the web view's scroll view:

Swift

self.webView.scrollView.subviews.forEach { $0.isUserInteractionEnabled = false }

Objective-C

for (UIView *subview in self.webView.scrollView.subviews)
{
    subview.userInteractionEnabled = NO;
}
Adulation answered 29/6, 2019 at 20:26 Comment(3)
VinneyCoyne's answer still allows the display of menu.. but prevents interaction with it. But this answer is perfect. No interaction except scrolling of the webview, which is what i want. Thanks!Ohg
I'm facing this error Value of type 'WKWebView' has no member 'scrollView'Vo
@KrunalNagvadia That's odd, it's a publicly accessible field of that class (see developer.apple.com/documentation/webkit/wkwebview/…). I assume you haven't inadvertently defined another type called WKWebView? Maybe it's some Xcode problem that can be fixed with a restart?Adulation
S
3

First, you have to give the delegate to your webkit then add below code. Swift 5.0

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    Activity.stopAnimating()
    let javascriptStyle = "var css = '*{-webkit-touch-callout:none;-webkit-user-select:none}'; var head = document.head || document.getElementsByTagName('head')[0]; var style = document.createElement('style'); style.type = 'text/css'; style.appendChild(document.createTextNode(css)); head.appendChild(style);"
    webView.evaluateJavaScript(javascriptStyle, completionHandler: nil)
}

What this code will do, we add programmatically css that will disable interaction in webview

Shelby answered 17/8, 2021 at 4:56 Comment(0)
S
1

These javascript lines will disable long presses and link touches by overriding the HTML. Frame based things like embedded youtube videos will still work.

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    webView.evaluateJavaScript("document.documentElement.style.webkitUserSelect='none'")
    webView.evaluateJavaScript("document.documentElement.style.webkitTouchCallout='none'")
    webView.evaluateJavaScript("var elems = document.getElementsByTagName('a'); for (var i = 0; i < elems.length; i++) { elems[i]['href'] = 'javascript:(void)'; }")
}
Shine answered 30/8, 2017 at 21:50 Comment(0)
H
0

this ignores the mouse (but passes it on to the next responder). you could choose not to do that and it would just "consume" the mouse event and nobody would know 😊

public class WebViewWhichIgnoresTheMouse: WKWebView
{
    override public func scrollWheel(with event: NSEvent)
    {
        self.nextResponder?.scrollWheel(with: event)
    }
    
    override public func mouseDown(with event: NSEvent)
    {
        self.nextResponder?.mouseDown(with: event)
    }

    override public func mouseUp(with event: NSEvent)
    {
        self.nextResponder?.mouseUp(with: event)
    }
    
    override public func mouseMoved(with event: NSEvent)
    {
        self.nextResponder?.mouseMoved(with: event)
    }
    
    override public func mouseEntered(with event: NSEvent)
    {
        self.nextResponder?.mouseEntered(with: event)
    }
    
    override public func mouseExited(with event: NSEvent)
    {
        self.nextResponder?.mouseExited(with: event)
    }
}
Hillman answered 12/6 at 1:18 Comment(0)
P
-4

You can do it as follow.

//-----------------------------------------------------------------------

#pragma mark - UIWebView Methods

//-----------------------------------------------------------------------

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {



    return YES;
}

//----------------------------------------------------------------

- (void)webViewDidStartLoad:(UIWebView *)webView {
//disable user interaction 
}

//----------------------------------------------------------------

- (void)webViewDidFinishLoad:(UIWebView *)webView{
//enable user interaction
}

//----------------------------------------------------------------

- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{
    //enable user interaction
}
Prehistoric answered 12/4, 2017 at 10:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.