Typical use: Tracking a scroll view

The flexible header can be provided with tracking scroll view. This allows the flexible header to expand, collapse, and shift off-screen in reaction to the tracking scroll view's delegate events.

Important: When using a tracking scroll view you must forward the relevant UIScrollViewDelegate events to the flexible header.

Follow these steps to hook up a tracking scroll view:

Step 1: Set the tracking scroll view.

In your viewDidLoad, set the trackingScrollView property on the header view:

Swift

headerViewController.headerView.trackingScrollView = scrollView

Objective-C

self.headerViewController.headerView.trackingScrollView = scrollView;

scrollView might be a table view, collection view, or a plain UIScrollView.

iOS 13 Collection Considerations

iOS 13 changed the behavior of the contentInset of a collection view by triggering a layout. This may affect your app if you have not yet registered cells for reuse yet. Our recomendation is to use view controller composition by making your collection view controller a child view controller. If this is not possible then ensure the correct order of operations by registering cell reuse identifiers before setting the Flexible Header's trackingScrollView.

Step 2: Forward UIScrollViewDelegate events to the Header View.

There are two ways to forward scroll events.

Option 1: if your controller does not need to respond to UIScrollViewDelegate events and you‘re using either a plain UIScrollView or a UITableView you can set your MDCFlexibleHeaderViewController instance as the scroll view’s delegate.

Swift

scrollView.delegate = headerViewController

Objective-C

scrollView.delegate = self.headerViewController;

Option 2: implement the required UIScrollViewDelegate methods and forward them to the MDCFlexibleHeaderView instance. This is the most flexible approach and will work with any UIScrollView subclass.

Swift

// MARK: UIScrollViewDelegate

override func scrollViewDidScroll(scrollView: UIScrollView) {
  if scrollView == headerViewController.headerView.trackingScrollView {
    headerViewController.headerView.trackingScrollViewDidScroll()
  }
}

override func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
  if scrollView == headerViewController.headerView.trackingScrollView {
    headerViewController.headerView.trackingScrollViewDidEndDecelerating()
  }
}

override func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) {
  let headerView = headerViewController.headerView
  if scrollView == headerView.trackingScrollView {
    headerView.trackingScrollViewDidEndDraggingWillDecelerate(decelerate)
  }
}

override func scrollViewWillEndDragging(scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
  let headerView = headerViewController.headerView
  if scrollView == headerView.trackingScrollView {
    headerView.trackingScrollViewWillEndDraggingWithVelocity(velocity, targetContentOffset: targetContentOffset)
  }
}

Objective-C

#pragma mark - UIScrollViewDelegate

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
  if (scrollView == self.headerViewController.headerView.trackingScrollView) {
    [self.headerViewController.headerView trackingScrollViewDidScroll];
  }
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
  if (scrollView == self.headerViewController.headerView.trackingScrollView) {
    [self.headerViewController.headerView trackingScrollViewDidEndDecelerating];
  }
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
  if (scrollView == self.headerViewController.headerView.trackingScrollView) {
    [self.headerViewController.headerView trackingScrollViewDidEndDraggingWillDecelerate:decelerate];
  }
}

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView
                     withVelocity:(CGPoint)velocity
              targetContentOffset:(inout CGPoint *)targetContentOffset {
  if (scrollView == self.headerViewController.headerView.trackingScrollView) {
    [self.headerViewController.headerView trackingScrollViewWillEndDraggingWithVelocity:velocity
                                                                    targetContentOffset:targetContentOffset];
  }
}