19

I am loading some content from the web into a UIWebView, but I'd like all links to be disabled in the UIWebView. Is this possible? I could parse the text, but I'm looking for something easier.

Tiago Almeida
  • 14,081
  • 3
  • 67
  • 82
Don Wilson
  • 2,303
  • 3
  • 26
  • 34

7 Answers7

54

You can give the UIWebView a delegate and implement the -webView:shouldStartLoadWithRequest:navigationType: delegate method to return NO; (except on the initial load).

That will prevent the user from viewing anything but that single page.

To provide an example requested in the comments... Start with allowLoad=YES and then:

- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType {
    return allowLoad;
}

- (void)webViewDidFinishLoad:(UIWebView*)webView {
    allowLoad = NO;
}
Brian White
  • 8,332
  • 2
  • 43
  • 67
Dave DeLong
  • 242,470
  • 58
  • 448
  • 498
  • How to avoid this for inital load only? – Praveenkumar Apr 16 '13 at 14:12
  • 2
    @Praveen I'd start by returning a variable that's initially `YES` but is set to `NO` in `-webViewDidFinishLoad:`. – Dave DeLong Apr 16 '13 at 21:01
  • No, i'm not getting, `webViewDidFinishLoad` is not a boolean method. Then, how can we return there? – Praveenkumar Apr 17 '13 at 09:10
  • @Praveen I'm saying that you use the fact that `-webViewDidFinishLoad` is called as an indication that the first load has finished. Once that method is invoked, you know that you can then return `NO` from the `shouldStartLoadWithRequest:...` method in the future. – Dave DeLong Apr 18 '13 at 01:55
  • Okay. Any examples related to this? – Praveenkumar Apr 18 '13 at 09:14
  • Set **allowLoad = YES;** before loading your INITIAL page. Once initial page finished loading (in webViewDidFinishLoad), set "allowLoad = NO;". So that, no further pages will be loaded. – NSPratik Jan 23 '15 at 09:24
11

Tested in Swift 4.0: This approach doesn't involve having an extra variable to test if this is the initial load or not. Simply check the type of request (in this case, LinkClicked) and return false in that case. Otherwise simply return true!

(Of course make sure you set the webView.delegate)

func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {
    if navigationType == .linkClicked {
        return false
    }
    return true
}
serenn
  • 1,828
  • 1
  • 15
  • 11
4

You can disable data detect from your webview.

[webView setDataDetectorTypes:UIDataDetectorTypeNone];
Jeffrey Neo
  • 3,693
  • 2
  • 26
  • 30
1

For swift 3:

Try removing the types you don't want to show as link from webView.dataDetectorTypes

webView.dataDetectorTypes.remove(UIDataDetectorTypes.all)
  • 1
    Please add some explanation to your answer instead of just posting one (unformatted) line of code. – Fabian S. Sep 07 '17 at 14:52
  • @FabianSchöner I edited to add some explanation and added the formatting. The solution works, voting it down would make people think the solution is wrong and not trying this solution. – Jeremiah Widjaja Sep 07 '17 at 15:36
  • i didnt downvote, i just added the comment. Thanks for making things clear by editing your answer! – Fabian S. Sep 07 '17 at 16:58
1

Another answer for Swift 3.0 :
Just give zero for don't detect any type link of yourWebView initial code

yourWebView.dataDetectorTypes =  UIDataDetectorTypes(rawValue: 0)
Chris Ho
  • 295
  • 4
  • 13
0

Simple answer that works in Swift 2.0:

yourWebView.dataDetectorTypes = UIDataDetectorTypes.None

Just implement it in the view controller where you are defining and using your web view and it will work flawlessly.

Jack Berstrem
  • 535
  • 1
  • 5
  • 22
  • @RainCast did you find a solution for YouTube (to prevent go on site and display only a video)? – user25 Mar 08 '19 at 13:47
0

I had a similar need and for some cases just using the webViewDidFinishLoad was not enough, so I used the webViewDidStartLoad to cover all cases:

func webViewDidStartLoad(webView: UIWebView) {
    startedLoading = true
}

func webViewDidFinishLoad(webView: UIWebView) {
    alreadyOpen = true
}

func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
    if startedLoading && alreadyOpen {
        // do something
        return false
    }else if startedLoading && !alreadyOpen{
        return false
    }else if !startedLoading {
        return true
    }
    return true
}

In some cases when the html was loaded but some resources, like images and some heavy assets inside the DOM were not the didFinishLoad method was not fired and the user could navigate in this "short" interval.

Felipe Jun
  • 722
  • 11
  • 22