Say I have 2 views (labels or textfields) with varying heights positioned above each other (not on top). I would like the group centred vertically in the superview.
I know I could use a dummy spacer view above and below and set equal height in storyboard. I'm no expert, but this doesn't seem right to me.
Can it be done in storyboard by setting the top constraint for the top view equal to the bottom constraint of the bottom view?
If your subviews' heights will change at runtime (either because you change the number of lines of text in them, or because you support Dynamic Type like a good iOS app should), then no, you cannot do this with just constraints. You either need an extra view or you need to change the constraint constants from code. If you go with an extra view (which I recommend), you can do it with a single extra view.
The simplest solution, if your deployment target is iOS 9 or later, is to put your subviews into a vertical
UIStackView and center the
UIStackView in the superview. You might not need any constraints directly on the subviews depending on the layout you want.
If you can't use a stack view, you can use a spacer view. First, set up vertical spacing constraints between your subviews to glue them together with whatever padding you want. Then add a spacer view next to the subviews. Set the spacer view to hidden. (Hidden views still participate in layout.) Constrain the spacer's top edge to your top subview's top edge, and constrain the spacer's bottom edge to your bottom subview's bottom edge. Then constrain the spacer to be vertically centered in its container (which should be the superview).
You also need to add horizontal constraints on the spacer to keep Xcode from complaining, but the horizontal size and position don't really matter since the spacer is hidden. So just put it somewhere convenient.
Here's the final set of constraints and layout:
The spacer is the skinny pink view.