Tim Dietrich

Custom Software Developer

Home Services Portfolio Blog About Contact Newsletter

iOS / Swift: UIRefreshControl Exception

While working on an iOS / Swift project today, I stumbled upon something that I found interesting. The app that I’m working on is simple: It pulls data from an API and displays it using UITable. The app includes a “pull to refresh” feature that is found in many data-driven iOS apps. When the users pulls, an API call is made to get “fresh” data, and the table is reloaded.

The code for the “pull to refresh” feature looks like this:

refreshControl = UIRefreshControl()
refreshControl.attributedTitle = NSAttributedString(string: "Pull to refresh")
refreshControl.addTarget(self, action: "refreshHandler", forControlEvents:
UIControlEvents.ValueChanged)
self.restaurantsTable.addSubview(refreshControl)

I was refactoring the code, and decided that if there is a problem getting data from the API, then I would hide the table. However, there’s a problem with this approach. If the table is hidden, then the “pull to refresh” feature no longer works - because the UIRefreshControl is managed by the table’s view controller.

I then modified the code slightly, so that the UIRefreshControl was managed by the view itself. I figured that even if the table was hidden, the refresh controller would still work properly. The updated code looks like this:

refreshControl = UIRefreshControl()
refreshControl.attributedTitle = NSAttributedString(string: "Pull to refresh")
refreshControl.addTarget(self, action: "refreshHandler", forControlEvents:
UIControlEvents.ValueChanged)
self.view.addSubview(refreshControl)

Well, the didn’t work either. It turns out that refresh controller can only be managed by table view controllers. The app will compile, but a “UIRefreshControl may only be managed by a UITableViewController” exception will be thrown.

So I've scrapped the idea of hiding the table. It was a nice idea, but not practical.