A very common interface design that we have started seeing with iOS7 apps is having a big cover photo on the top of table views which extends all the way up to the status bar. Here’s an example. However, by default, iOS adds an inset to the scroll views so that the content starts from below the top layout guide. Its easy to put everything back to top, though. All we need is to set the contentInset
of tableview to UIEdgeInsetsMake(0, 0, 0, 0)
.
Lets try to put a refresh control to our tableview now. I like to use a UIViewController
instead of a UITableViewController
to have more control over the views. Here’s a hack to make the refresh control work with UIViewController
.
// Add pull to refresh control.
UITableViewController *tableViewController = [[UITableViewController alloc] init];
tableViewController.tableView = self.tableView;
self.refreshControl = [[UIRefreshControl alloc] init];
[self.refreshControl addTarget:self action:@selector(doRefresh) forControlEvents:UIControlEventValueChanged];
tableViewController.refreshControl = self.refreshControl;
Now try pulling the tableview down. So, we have the refresh control, but it is hidden behind the navbar. The pull to refresh control starts from the content inset for the tableview and we already set it to 0
to have our cover image nicely fit behind the navbar. Time for another quick hack to get this to work. We need to offset the content in the header view by 64 pixels (the length of the top layout guide) and reset the top content inset for tableview to 64 pixels so that the cover image starts from behind the navigation bar and the pull to refresh from below.
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) {
self.tableView.contentInset = UIEdgeInsetsMake(self.topLayoutGuide.length, 0, 0, 0); // This is the default and might not be necessary
self.headerContainerViewConstraint.constant = -self.topLayoutGuide.length;
self.tableView.tableHeaderView.frame = CGRectMake(self.tableView.tableHeaderView.frame.origin.x, self.tableView.tableHeaderView.frame.origin.y, self.tableView.tableHeaderView.frame.size.width, self.tableView.tableHeaderView.frame.size.height - self.topLayoutGuide.length);
}