UIScrollView AutoLayout Vertical Only

36,527

Solution 1

For disabling the horizontal scroll, you can set the content size in the (void)scrollViewDidScroll method.

[self.scrollView setContentOffset: CGPointMake(0, self.scrollView.contentOffset.y)];

You'll also want to set the directional lock so only 1 scroll direction is used at a time. https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIScrollView_Class/index.html#//apple_ref/occ/instp/UIScrollView/directionalLockEnabled

self.scrollView.directionalLockEnabled = YES;

Solution 2

You can do this entirely using constraints and it's really easy.

The UIScrollView just needs to understand how much width and space it has inside it. So it needs to have something pinned to the Leading, Trailing, Top & Bottom constraints. Also the width and height of the content needs to be fixed (this does not mean I have to specificy it. I can still use constraints to achieve this.)

  1. Add a UIScrollView and position as required.
  2. Add a UIView inside the UIScrollView for the content.
  3. Set the Leading, Trailing, Top & Bottom constraints of the content UIView to be 0.
  4. Add an Equal Width constraint to the UIScrollView and UIView. This will make it vertically scrolling only.
  5. You now need to set the height of the content UIView. You can then either specify the height of the content view (blech) or use the height of the controls contained within by making sure the bottom control is constrained to the bottom of the content view.

I did this and it worked a treat.

Solution 3

To summarize the Leszek S' answer:

In order to have a vertically scrolling view, all the views inside the scroll view must have their width constraint set. Easy to just set to the scroll view's superview.

The reason is that the scroll view will not scroll horizontally so as long as none of its subviews need to scroll horizontally. For example, if you have a label, set to 0 lines, auto layout will try to make the label as wide as it can before it starts adding lines and line breaks. If there are no explicit width constraints on the label it'll just make the scroll view content area wider. Constraints for trailing to the scroll view are ignored.

If you have a bunch of views, you might want to put them inside a single containing view like in that video. For my case, I only have 5 or 6 labels which can dynamically change height, but should never change width so I just made them all the same width as the scroll view. And bingo, vertically scrolling view with labels that grow or shrink depending on the text.

Solution 4

Tested with Swift 4-5 in Xcode 12.1 Vertical Scroll View Setup

  1. Add a Scroll View and set top, bottom, left and right constraints to 0. enter image description here
  2. Remove the Scroll View "Content Layout Guides" by un selecting it in the Size inspector.enter image description here
  3. Add uiview to Scroll View. enter image description here

4.We need to set the constraints of the uiview in relation to the scroll view. Control click the uiview and then attach to scroll view.

enter image description here

  1. This brings up the constraints between the two.

enter image description here

  1. Hold down shift to select more than one. We need to add Equal Widths, Equal Heights, Leading, Trailing, Top and Bottom.

enter image description here

  1. Edit Equal Height to: Superview priority to 250 from 1000.

enter image description here

  1. Now add the content. For simplicity I added an image and a label with 0 lines in Attribute inspector and lots of text in view did load.

enter image description here

  1. Final Result!

enter image description here

Solution 5

I have written a function that allows to scroll content vertically but not horizontally. It creates a UIView with limited width inside scrollview and embeds all scrollview subviews in it.

TegScrolledContent.createContentView(scrollView)

https://github.com/exchangegroup/scrollable-content-ios

enter image description here

Share:
36,527
Gasim
Author by

Gasim

Updated on November 07, 2020

Comments

  • Gasim
    Gasim over 3 years

    I want to get the AutoLayout working with the UIScrollView and am having a little trouble with it. Here is what I did:

    1. Add a UIScrollView inside the Main View with frame: [top: 0, left: 0, width: 320, height: 568]

    2. Add UIView "ContentView" inside the UIScrollView with frame and bgcolor black: [top: 0, left: 0, width: 320, height: 568]

    3. Setup UIScrollView constraints: [top: 0, bottom: 0, left: 0, right: 0]

    4. Setup "ContentView" constraints: [top: 0, bottom: 0, left: 0, right: 0]

    5. Align the items inside the "ContentView"

    6. Set Main View bgcolor to gray (to see what's going on)

    Here is a screenshot of the problem:

    Screen Shot1

    For some reason, the constraints make the content view be in the middle of the screen. Also, it scrolls in every direction. I want the content to be scrollable only in vertical direction like in UITableView. so that I can't move it like below:

    Screen Shot

    What am I doing wrong? I have checked all the tutorials and answers I can find in StackOverflow and Google, and no one actually has just a bizarre problem, so I am asking for help.

    EDIT: I also added ContentView's width and height as constraints and that didn't help either.