Customising UIWebView

      2 Comments on Customising UIWebView

If you want to display complex layout you could easily spend a week working on one view controller. Fortunately, there’s an easier way. You can use a web view to do this. In this article, we’ll take a web page, strip some elements from it, and display it in our app.

We’ll be using one of the articles from this blog as an example web page. We’ll strip HTML elements from it, like header, footer, and some others. We’ll also add a list of internal hosts. If you tap on a link that’s not on the list of internal hosts, the link will open in Safari, otherwise, the link will open within the web view.

Stripping HTML Elements

I won’t go into details of how HTML works, what’s important for you to remember is that elements of a web page can be identified using an element id (or class). We’ll use this to find our elements and remove them.

If you open this blog in Safari on your iPhone you’ll see something like this:

And the footer will look something like this:

We’ll strip this page down and just keep the original text. So, the header and everything below the ‘More resources’ section will be gone.

Let’s quickly set up the UI, create a new project and add a couple of elements, like so:

The big white rectangle in the middle is the web view 🙂 Hook all the buttons and actions to your view controller. Before we start coding, don’t forget to allow arbitrary loads, otherwise, you won’t be able to load the page. So add ‘NSAppTransportSecurity’ and set ‘NSAllowsArbitraryLoads’ to ‘YES’ in your Info.plist:

Let’s code 🙂

Let’s make sure we hooked everything up. We’ll load a web page:

If we build and run, the page should load. And it should look the same as if we loaded it in Safari.

We’ll have an array of HTML element IDs and classes that we’ll remove, and we’ll have a method that will iterate over this array and remove the elements one by one. Let’s take a look at the method:

In the ‘removeElement’ method we’re using a bit of JavaScript to fetch the element and then we remove the element from its parent. UIWebView is able to execute JavaScript on the fly, which works great for us. So we can just execute this small piece of JavaScript by calling ‘stringByEvaluatingJavaScript’. We’ll do something similar to find the element by its class name, and remove the first element we find with that class name.

Set your view controller as the delegate of your webView and in the ‘webViewDidFinishLoad’ just call ‘removeElements’ method.

If you inspect your web page in Chrome browser you can easily find the IDs of the elements you want to remove, for example, this is the header element that I want to get rid of:

If you’re using this blog as an example, just add the ‘masthead’ into the ‘elementsToRemove’ array, build and run and hopefully, you won’t see the header anymore:

Bye, bye header 🙂 You can use Chrome to find the IDs of the remaining elements you want to remove, just add all of them in that array. This is what I ended up with:

We managed to strip all but the main content of the web page, the footer looks pretty clean:

Internal Hosts

One other thing I wanted to do was to keep the navigation within the agostini.tech host in the web view, and to open all the other links in Safari. So, for example, if you tap on the ‘Offline Voice Command and Text-ToSpeech’, that page would load in the web view, but if you tapped on ‘DADependencyInjection’ (a GitHub repo), that link would open in Safari. This might sound complicated, but it’s quite simple to implement.

We’ll add all the hosts in an array, and in one of the web view delegates, we’ll check if the destination is in the list of internal hosts, if it’s not, we’ll open the link in Safari. Easy, right? Let’s see some code… The array is obvious, but let’s mention it anyway:

Next, we need one utility method to check if a URL’s host is in the array of hosts:

In the delegate callback we’ll check if the next URL request’s host is in the list, and open the page in Safari if it isn’t:

That’s pretty much it. WebView will call the delegate when it’s about to load the next request, which will give us the option of proceeding with the load, or not. We’ll intercept it here and load it in Safari if the host is not in the array.

Favorites

Just as a little extra, I added a favourite button. You can add/remove favourites. Maybe you’ll find it useful, so I’ll just mention it here quickly. The code is simple:

And the IBAction:

Conclusion

I was thinking of creating an app for my blog, just for fun. I didn’t want to spend days on the layout for the post details, so I came up with the idea of using a simple web view. Obviously, I didn’t want the full page, but the stripped down version, hence, the post 🙂 I was surprised to see how well this actually works, and how much time I saved up. It takes just a couple of hours to set this up, and it looks great.

This was one of the shorter posts I wrote, I hope you’ll find it short and useful 🙂 All the code is on GitHub, so check it out.

Have a nice day 🙂

Dejan.

More resources

0

2 thoughts on “Customising UIWebView

  1. ramakrishna chunduri

    The article is a lot helpful. Few examples i can think of are

    In some cases where we are building an app for websites but want to clean clutter around the login screen we can do that.

    If we wish to have separate controllers for one article we can have example one for content and another for comments and ratings.

    Thanks a lot for such a detailed article.

    Reply
    1. Dejan Agostini Post author

      I’m very happy you found the article useful. Thank you very much for the kind words, and you’re welcome. I just hope you’ll find some of my other articles useful as well.

      Those are great examples. The reason I did this was because I wanted to display my blog articles in a web view, without all the clutter. If I had that problem, I’m sure other people had the same one. So I decided to share what I’ve learned.

      Have a nice day 🙂
      Dejan.

      Reply

Leave a Reply