Search code examples
iosuiscrollviewautolayoutfooteruistackview

ScrollView with StackView and fixed footer outside


Xcode 10, Swift 5 (this should be doable purely in the Storyboard)

The current layout:

- ChildView (child View of very first default view)
    - ButtonView
        - ScrollView
            - VerticalStackView
                - Button
                - Button
                - ...
    - FooterView
         - HorizontalStackView
            - Button A
            - Button B

What contraints do I need to always keep the Footer View at the bottom and make the UIStackView scroll behind it, while still maintaining a fixed height for each button in the UIStackView?


Solution

  • This setup seems to attract multiple problems, from the buttons inside not being clickable (or UITextFields that can't be interacted with), to the UIScrollView not being scrollable or a "Content Size Ambiguity" error (described here) - just because a single constraint isn't set properly.

    The result:

    enter image description here

    If there are less buttons that can all be displayed at the same time, it won't be scrollable but instead simply display the black background below the last button.

    How to get there:

    The constraints are set using the "add new constraints" button below the preview window.

    enter image description here

    ChildView:

    • Trailing/Leading/Bottom: 0 to Superview
    • Equal Height: to Safe Area:
      • Control-drag from the ChildView to the Safe Area and pick "Equal Heights"

    1. FooterView:

    • Trailing/Leading/Bottom: 0 to Superview
    • Height: Equals 50
    • Top to ButtonView:
      • Control-drag from the FooterView to the ButtonView
      • Choose "Top"
      • Click on the new constraint to open it in the inspector (FooterView.Top equals ButtonView.Bottom)

    enter image description here

    2. ButtonView:

    • Trailing/Leading/Top: 0 to Superview
    • Bottom to FooterView (already explained above)

    2.1. ScrollView (black):

    • Trailing/Leading/Bottom/Top: 0 to Superview
    • The Bottom/Top constraints keep the ScrollView from "spilling over"

    2.1.1. VerticalStackView:

    • Alignment/Distribution: Fill
    • Trailing/Leading/Bottom/Top: 0 to Superview
    • Equal width to ButtonView:
      • Control-drag from the VerticalStackView to the ButtonView and pick "Equal Widths"
      • This disables the horizontal scrollbar of the ScrollView

    2.1.1.1. Button (gray):

    • Height: 50
    • The VerticalStackView takes care of the rest

    Of course you can also replace the buttons in the 'UIScrollView' with views to create some type of form.