Skip to content

Instantly share code, notes, and snippets.

@dmishe
Forked from calebd/Readme.markdown
Created July 25, 2013 04:02
Show Gist options
  • Save dmishe/6076823 to your computer and use it in GitHub Desktop.
Save dmishe/6076823 to your computer and use it in GitHub Desktop.

Step 1: Configure the table view.

  • Set a view as the table footer
  • Set the background color to clear.

Step 2: Set the default table view values when your view loads. The values and variables seen here are explained below.

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.tableView.contentInset = UIEdgeInsetsMake(CGRectGetMaxY(self.headerView.frame) - 43.0, 0.0, 0.0, 0.0);
    self.tableView.scrollIndicatorInsets = self.tableView.contentInset;
    self.tableView.contentOffset = CGPointMake(0.0, -CGRectGetMaxY(self.headerView.frame) + 43.0);
}

Step 3: Update the table footer frame and content insets properties every time your view lays itself out or any time your table view content changes.

- (void)viewWillLayoutSubviews {
    [super viewWillLayoutSubviews];
    
    // Update footer view frame
    UIView *footerView = self.tableView.tableFooterView;
    footerView.frame = CGRectMake(0.0, 0.0, self.tableView.bounds.size.width, self.tableView.bounds.size.height);
    self.tableView.tableFooterView = footerView;
    
    // Update content insets
    UIEdgeInsets insets = self.tableView.contentInset;
    if (self.tableView.contentSize.height - footerView.bounds.size.height > self.tableView.bounds.size.height) {
      insets.bottom = -self.tableView.bounds.size.height;
    }
    else {
      insets.bottom = self.tableView.bounds.size.height - self.tableView.contentSize.height;
    }
    self.tableView.contentInset = insets;
}

Step 4: Update scroll indicator insets every time the scroll region change.

  • The value 44.0 is the height of the region you want to remain uncovered during scrolling
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    CGFloat offset = scrollView.contentOffset.y;
    CGFloat base = self.headerView.bounds.size.height - 44.0;
    CGFloat delta = base + offset;
    scrollView.scrollIndicatorInsets = UIEdgeInsetsMake(fmaxf(0.0, base - delta), 0.0, 0.0, 0.0);
}

Step 5: Tell the scroll view where to land when scrolling is done.

  • The value headerView is the view that is static behind the table view.
  • The value 43.0 is one less than the height from above (44.0) that is the height of the region you wish to remain uncovered. This is one less because UITableView puts a 1 point border at the top of its first cell that is normally hidden from view. Handling the value like this makes it such that that 1 point border is below the headerView when the table view is at rest.
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
    if ((*targetContentOffset).y > 0.0 || (*targetContentOffset).y < -self.headerView.bounds.size.height) {
        return;
    }
    CGFloat middle = self.headerView.bounds.size.height / 2.0;
    if (velocity.y == 0.0) {
        if (-(*targetContentOffset).y > middle) {
            (*targetContentOffset).y = -CGRectGetMaxY(self.headerView.frame) + 43.0;
        }
        else {
            (*targetContentOffset).y = -1.0;
        }
    }
    else if (velocity.y > 0) {
        (*targetContentOffset).y = -1.0;
    }
    else {
        (*targetContentOffset).y = -CGRectGetMaxY(self.headerView.frame) + 43.0;
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment