-
Notifications
You must be signed in to change notification settings - Fork 1
DDD 4.10. Displaying a Refresh Control for Table Views
You want to display a nice refresh UI control on top of your table views that allows your users to intuitively pull down the table view in order to update its contents.
Simply create a table view controller (as discussed in Recipe 4.9) and set its refresh Control property to a new instance of UIRefreshControl class, as shown here:
- (id)initWithStyle:(UITableViewStyle)style{ self = [super initWithStyle:style]; if (self) { [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:CellIdentifier]; self.allTimes = [NSMutableArray arrayWithObject:[NSDate date]]; /* Create the refresh control */ self.refreshControl = [[UIRefreshControl alloc] init]; self.refreshControl = self.refreshControl; [self.refreshControl addTarget:self action:@selector(handleRefresh:) forControlEvents:UIControlEventValueChanged]; } return self; }
Create a new instance of this class simply by calling its init method. Once you are done, add this instance to your table view controller, as described in the Solution section of this recipe. Now you’ll want to know when the user has triggered a refresh on your table view. To do this, simply call the addTarget:action:forControlEvents: instance method of your refresh control and pass the target object and a selector on that object that takes care of the refresh for you. Pass UIControlEventValueChanged to the forControlE vents parameter of this method.
So let’s start in the implementation file of our table view controller and define our refresh control and our data source:
#import "ViewController.h" static NSString *CellIdentifier = @"Cell"; @interface ViewController () @property (nonatomic, strong) NSMutableArray *allTimes; @property (nonatomic, strong) UIRefreshControl *refreshControl; @end
The allTimes property is a simple mutable array that will contain all the instances of NSDate in it as the user refreshes the table view. We have already seen the initialization of our table view controller in the Solution section of this recipe, so I won’t write it again here. But as you saw there, we have hooked the UIControlEventValueChanged event of our refresh control to a method called handleRefresh:. In this method, all we are going to do is add the current date and time to our array of dates and times and then refresh the table view:
- (void) handleRefresh:(id)paramSender{ /* Put a bit of delay between when the refresh control is released and when we actually do the refreshing to make the UI look a bit smoother than just doing the update without the animation */ int64_t delayInSeconds = 1.0f; dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ /* Add the current date to the list of dates that we have so that when the table view is refreshed, a new item will appear on the screen so that the user will see the difference between the before and the after of the refresh */ [self.allTimes addObject:[NSDate date]]; [self.refreshControl endRefreshing]; NSIndexPath *indexPathOfNewRow = [NSIndexPath indexPathForRow:self.allTimes.count-1 inSection:0]; [self.tableView insertRowsAtIndexPaths:@[indexPathOfNewRow] withRowAnimation:UITableViewRowAnimationAutomatic]; }); }
Last but not least, we will provide the date to our table view through the table view’s delegate and data source methods:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ return self.allTimes.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; cell.textLabel.text = [NSString stringWithFormat:@"%@", self.allTimes[indexPath.row]]; return cell; }