UIRefreshControl in iOS 10

UIRefreshControl in iOS 10

Did you know that adding a UIRefreshControl in iOS 10 to a table view, a collection view, or a scroll view has never been easier? UIRefreshControl is now a first class citizen in all of these scrollable views and officially supported by the iOS SDK. Having fought through hacked solutions to use a UIRefreshControl in anything but the officially supported UITableViewController in the past, I’m really pumped to see this. This change for iOS 10 first caught my eye in the WWDC 2016 session, What’s New in UICollectionView in iOS 10 (which was a really good session by the way).

How It Works

The key to easily adding a UIRefreshControl to a UITableView, a UICollectionView, and a UIScrollView is the UIRefreshControlHosting protocol. Just like UIRefreshControl in iOS 10, this is also new in iOS 10. It’s a protocol adopted by UIScrollView. And coincidentally, UITableView and UICollectionView inherit from UIScrollView so they easily get this behavior.

Adding a UIRefreshControl in iOS 10

Here’s how simple it is to add a UIRefreshControl in iOS10:

let tableView = UITableView()
let rc = UIRefreshControl()
tableView.refreshControl = rc

Yep, it’s that dirt simple. Want to add a UIRefreshControl to a UIScrollView? It’s just as easy!

let scrollView = UIScrollView()
let rc = UIRefreshControl()
scrollView.refreshControl = rc

And want to add it to a UICollectionView? Well, you probably get the idea:

let collectionView = UICollectionView()
let rc = UIRefreshControl()
scrollView.refreshControl = rc

Now don’t forget to add a target to the UIRefreshControl so it has some behavior associated with it. Luckily, nothing has changed with that API, so it’s just as you remember it from pre iOS 10 days. Here’s a full example with a UITableView:

override func viewDidLoad() {
  super.viewDidLoad()
  let tableView = UITableView()
  let rc = UIRefreshControl()
  rc.addTarget(self, action: #selector(TableViewController.refresh(refreshControl:)), for: UIControlEvents.valueChanged)
  tableView.refreshControl = rc
  view.addSubview(tableView)
}

func refresh(refreshControl: UIRefreshControl) {
  tableView.reloadData()
  refreshControl.endRefreshing()
}

Refreshingly Simple

If you got this far, you probably aren’t rolling your eyes at how easy this is. If you’re questioning whether this is worth a blog post or not, fine. I believe it is. This is a subtle, yet awesome API change coming in iOS 10. I love to see that Apple continues to refine their API and adding niceties like this for developers. I look at this change and think, “Ya, this is how it always should have been.” Thank you, Apple. Has there been anything else on the edges that you’ve noticed and felt good about?

Happy cleaning.

2 thoughts on “UIRefreshControl in iOS 10”

  1. Hi! I have a view controller with a table view and a refresh control right as you described in this article. When I rotate screen during the refresh, refresh control sticks. I’ve tried to add .endRefreshing() on the viewWillTransition and tableview.refreshData() in vain. None of the solutions I could find works. Could you help? Thank you!

  2. It’s also available on ios 8 and 9 but not like that, you can use it like this, yes it’s strange that this is not documented but it works
    scrollView.addSubview(refreshControl)
    instead of
    scrollView.refreshControl = rc

Leave a Reply

Your email address will not be published. Required fields are marked *