Using a RefreshControl to Reload a WKWebView

When you use the WKWebView control to render a web page in your iOS application, it doesn’t come with the usual browser controls that users may expect. It renders the webpage without a toolbar or functions like Back, Forward, or Reload. I’m going to show you how to use the iOS UIRefreshControl to reload a web page rendered in a WKWebView.

1. Create a WKWebView

Start by adding an empty view to your ViewController. You’ll use it as a container to host your WKWebView. The first step is to drag a UIView onto the storyboard scene and set the constraints to fill the view.

adding container to hold wkwebview

Add an outlet to the container view so you can access it through code. Next, create the WKWebView, add it to your container, and constrain it to the edges of the container view. Now you can load whatever website you like.


class ViewController: UIViewController {
    @IBOutlet var webViewContainer: UIView!

    var webView: WKWebView?
    
    override func viewDidLoad() {
        super.viewDidLoad()

        webView = WKWebView(frame: webViewContainer.bounds) // size will be determined by auto-layout
        if let webView = webView {
            webView.translatesAutoresizingMaskIntoConstraints = false
            webViewContainer.addSubview(webView)
            let bindings: [String: AnyObject] = ["webView": webView]
            webViewContainer.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[webView]|",
                                                               options: NSLayoutConstraint.FormatOptions(rawValue: 0), metrics: nil, views: bindings))
            webViewContainer.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[webView]|",
                                                               options: NSLayoutConstraint.FormatOptions(rawValue: 0), metrics: nil, views: bindings))

            let url = URL(string:"https://www.atomicobject.com")
            let request = URLRequest(url:url!)
            webView.load(request)
        }
    }
}

If you run the project, you should see your app start up and display whatever webpage you have loaded. However, if you need to refresh the page, there is no way to do that.

Many mobile apps use the pull-to-refresh gesture. Let’s get that working next.

2. Adding the UIRefreshControl

The WKWebView already contains a scrollview. All you need to do is create the refresh control, assign a target function that will get called when a user initiates a refresh, and attach the refresh control to the scrollview.

Add the following code after you set up the constraints, but before you load a request.


let refreshControl = UIRefreshControl()
refreshControl.addTarget(self, action: #selector(refreshWebView(_:)), for: UIControl.Event.valueChanged)
webView.scrollView.addSubview(refreshControl)
webView.scrollView.bounces = true

Next, you need to define the refreshWebView(_:) function that you assigned as the target for the refresh control. The WKWebView already has a reload function that you can call. The last step is to tell the refresh control to stop spinning.


@objc
func refreshWebView(_ sender: UIRefreshControl) {
    webView?.reload()
    sender.endRefreshing()
}

Notice that we marked the function with the @objc attribute. This allows the function to be called from the Objective-C runtime. If you build and run, you can now use the pull-to-refresh gesture to reload the website.

pull to refresh the wkwebview