How to make iOS Stretchy Header with Auto Layout
Issue #27
Stretchy header is cool. People are familiar with changing frames to achieve this, like Design Teardown: Stretchy Headers. But with Auto Layout, we can achieve this with much nicer declarative constraints
The demo project is StretchyHeader
I use SnapKit to make it clear what constraints we need
scrollView
The scrollView
should pin its 4 edges to the ViewController 's view
1 | func setupScrollView() { |
scrollViewContentView
The scrollViewContentView
must pin its 4 edges to the scrollView
to help determine scrollView
contentSize
The height of scrollViewContentView
is determined by its subviews. The subviews inside must pin their top
and bottom
to the scrollViewContentView
1 | func setupScrollViewContentView() { |
header
The header
must pin its top to the scrollView
parent, which is the ViewController 's view
Read the title
section, you ‘ll see that in order to make header
stretchy, it must be pinned top and bottom
But if we scroll up, there will be a constraint conflict between these pinned top
and bottom
constraints
So we must declare headerTopConstraint
priority as 999, and headerLessThanTopConstraint
1 | func setupHeader() { |
title
The title
must pin its top to the scrollViewContentView
to help determine scrollViewContentView
height
The title
must also pin its top the header
bottom in order to make header
stretchy
1 | func setupTitleLabel() { |
scrollViewDidScroll
The header is always pinned to the top, unless you adjust it, here in scrollViewDidScroll
Here I use Constraint
, which is a class from SnapKit
, but the idea is to change the constant
of the NSLayoutConstraint
1 | func scrollViewDidScroll(scrollView: UIScrollView) { |
By the way, did you just learn the story of One Piece :]