Pull-to-Refresh

There’s one other common table task we should attend to with our table: we haven’t given the user a means of refreshing the tweets. We had this in the last chapter with the Show My Tweets button, but now that our whole view is a table (for now, anyway), there’s no way to expose this functionality. It doesn’t matter now with our mock data, but it will matter a lot if we can’t get new tweets from the Internet. How are we going to fix that?

Many table-based iOS apps use a pull-to-refresh gesture, in which scrolling to the top of the table and then pulling down to scroll further is interpreted as a request for the app to refresh its data. There were a variety of third-party implementations of this gesture for a number of years, and in iOS 6, Apple provided a standard implementation in the form of the UIRefreshControl class.

The UITableViewController that our ViewController subclasses has a refreshControl property, meaning we inherit it, so all we need to do is to populate that with a refresh controller and default behavior will take care of the UI for us. In fact, the ease of using the refresh controller is one reason to choose to subclass UITableViewController, rather than have a plain UIViewController that also happens to implement the UITableViewDataSource protocol.

Looking at the documentation, the UIRefreshControl is a subclass of UIControl and acts somewhat like a button or another generic control; when triggered, it sends an event called UIControlEventValueChanged. For us to do anything with it, we need to get a callback when that event occurs. We do that with the UIControl method addTarget(action:forControlEvents:). This method takes an object to call back to (such as our view controller), a method to call (which we’ll write), and the relevant events for this callback (UIControlEventValueChanged).

So let’s create and set up a suitable UIRefreshControl when our view controller first comes to life, in viewDidLoad:

 override​ ​func​ viewDidLoad() {
 super​.viewDidLoad()
  reloadTweets()
 let​ refresher = ​UIRefreshControl​()
  refresher.addTarget(​self​,
  action: ​"handleRefresh:"​,
  forControlEvents: .​ValueChanged​)
  refreshControl = refresher
 }

The action, meaning the method that’s invoked by the callback, is passed as a selector, a string that uniquely identifies a method signature. In this case, we’re promising to write a method called handleRefresh that will take one parameter, as indicated by the single colon character. By convention, these action methods take a single argument to identify the sender, and have a return type of IBAction, so they can be used for connections in the storyboard (so we could also connect it with the Interface Builder GUI rather than with code if we wanted to). So let’s write this action method:

1: @IBAction​ ​func​ handleRefresh (sender : ​AnyObject​?) {
2:  parsedTweets.append(
3: ParsedTweet​(tweetText: ​"New row"​,
4:  userName: ​"@refresh"​,
5:  createdAt: ​NSDate​().description,
6:  userAvatarURL: defaultAvatarURL)
7:  )
8:  reloadTweets()
9:  refreshControl?.endRefreshing()
10: }

This action method does three things:

  • On lines 2--7, we append a new ParsedTweet to the parsedTweets array that serves as the table’s data model. Notice that on line 5, we create a new NSDate object (which defaults to the current instant in time), and then use that class’s description method to turn it into a string.

  • We call our existing reloadTweets method on line 8.

  • Finally, on line 9 we call endRefreshing to tell UIRefreshControl to hide the spinning wheel. UIRefreshControl also has a beginRefreshing method to show the spinner, but this is called for us automatically as UITableViewController processes the pull gesture.

images/tables/custom-cells-with-refresh-control-mock-data.png

When we run now, the spinner appears atop the table when we scroll to the top and pull again, as seen in this figure. This starts a reload of the Twitter data and dismisses the spinner, with a new row added to the table view when the reload is done. Try pulling slowly to see how the spinner only starts spinning and reloading once the drag gesture reaches a certain point. It’s a handy gesture!

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.45.137