Add Scroll View to your root view and add pin it with 4 constraints. Your root view should have only 1 child which is the scroll view.

Create new “container” view and add it to the scroll view. Scroll view can have only one child view. This was mentioned by Natasha and I always follow this rule since, I lost many hours when I didn’t know about this.

Add constraint for container view width to be equal with root view width.

Add footer view and pin it to the bottom.

Scroll view can’t function when content height is unknown. Add height constraint outlet. In this example for my content I have single label, I don’t set container view height because it will change depending on label height. I pinned label to its superview. Make sure your Storyboard file doesn’t have error messages and layout conflicts resolved.

At this point you should get something like this in your Interface Builder. We still have some work to do. Open view controller and add following code.

So far I have no content and we had to increase label heigh so footer sticks to the bottom as design required. If I set text for the label it will truncate which I don’t want. I had to disable this constraint and allow scrolling.

labelHeightConstraint.isActive=false

iPhone X

I thought I was done but when I run the code I realised it was broken on new iPhone X. Here’s code snippet that helped me.

The key is viewDidAppear because safe area insets equal to zero in viewDidLoad. I also had to disable landscape layout.

I noticed that iPhone X screen is very tall so all my text was visible and footer was in the middle of the screen, I had to activate constraint again. Only disable height constraint when you have many pages of content, iPhone X can fit surprising amount of information.