14

In xcode 5 using storyboards how would one make a fully operational vertical scrolling scrollview, with AutoLayout ON?
Considering the subviews have hierarchy:

  1.UIView  
    2.UIScrollView
      3.UIView (lets call this UIDetailView to make things easier)

Please be specific from code to constraints to wether any of the views HAS to be smaller etc.

KeVal
  • 351
  • 1
  • 4
  • 15

5 Answers5

12

UIScrollView with Autolayout within Storyboards Just Works

I've seen a number of people recommending the 'Container View' approach, AKA brute force, to solving the problem that they don't understand. It is non-optimal since you now have lost a big advantage of the scrollview by making it think the content is the entire scrollview rather than the subviews immediately attached to the scrollview.

Here is how I did it in the example that follows

--UIScrollView
  |-> UITextView
  |-> UILabel
  |-> UIOtherStuff

When placing a UIScrollView into a UIView in a Storyboard just pin the edges to the 4 sides of the UIScrollView to the UIView. Now add your content to the UIScrollView making sure that you provide a minimum of two constraints for each dimension. The great thing about Autolayout is that it figures out how big the contentSize of the scrollview, or UILabels for that matter, needs to be based upon the size of the content inside it. AKA intrinsicContentSize. So if you are given a warning 'Ambiguous content size for scrollView' you know that you have not given the content enough constraints. For example, you might have given Top, Bottom, Left, Right spacing distance between views but the subview you're constraining needs a height too since an infinite vertical plane like this UIScrollView could assume your view was from zero to infinitely high.

To put it another way the Apple guide on Autolayout by Example makes a simple 3 point plan for success:

  1. Create the scroll view.
  2. Place the UI element inside it.
  3. Create constraints that fully define the width and height of the scroll view content.

That top TextView with 'Min melding til' is also growing as you type more lines into it and the whole ScrollView grows to contain it. While I override the UITextView class to return a modified height constraint, the ScrollView itself works correctly without coding.

One last thing, lots of posts related to Autolayout try the magical fix-all incantation translatesAutoresizingMaskIntoConstraints = NO. This is only necessary if the view is created programmatically.

Example of UIScrollView with Autolayout

Cameron Lowell Palmer
  • 21,528
  • 7
  • 125
  • 126
  • 1
    This was extremely helpful. Using a UIImageView relies on intrinsic content size, whereas this provides a way to lay out any content into a scrollview. Thanks! – ryanbillingsley Jun 18 '14 at 19:36
10

This blog post details how to use a UIScrollView with Autolayout ON, using a pure autolayout approach. Note though that all constraints in the blog post are defined through the Storyboard.

The approach in the post assumes the following hierarchy:

1. View (main view of my UIViewController)
  2. Scroll View (UIScrollView)
     3. Container View (UIView)
       4. Content View (e.g. UIImageView)

I guess the Container View will be your UIDetailView, and the Content View will be any UIView inside your UIDetailView.

https://happyteamlabs.com/blog/ios-how-to-use-uiscrollview-with-auto-layout-pure-auto-layout/

Dj S
  • 10,232
  • 1
  • 21
  • 24
  • how to actually set the constrains? the initial apple document seems quite complicated. Is there any way you could provide a full plan from what to do in storyboard and what in code? – KeVal Oct 01 '13 at 10:19
  • The link above details the constraints. The only missing part of the tutorial are screenshots. Is that what you need? – Dj S Oct 02 '13 at 01:25
  • Well actually I got the constraints now but i can't get scrollview to scroll for the desired vertical length. – KeVal Oct 03 '13 at 14:34
  • 2
    I can't get it to scroll at all. – KeVal Oct 03 '13 at 20:37
  • If you have correctly set the constraints and if your content view is greater in size than the viewable area, your scroll view should be able to scroll. Do you want to create an example github project so I can look into your problem? – Dj S Oct 07 '13 at 02:31
  • [link](https://github.com/storoz/scroll) Ive made this project with exactly the same scrollview properties – KeVal Oct 10 '13 at 18:00
7

The documentation clearly states how to do this: A UIScrollView in auto-layout will always resize itself to fit the content (UIDetailView).

So you have to set up your views like this:

  • UIView: Position with constraints.
  • UIScrollView: Bind to UIView with constraints.
  • UIDetailView: Set size (intrinsic content size), max out compression-resistance, set top-, bottom-, leading- and trailing constraints to UIScrollView to 0 manually.
patric.schenke
  • 942
  • 11
  • 19
  • 1
    You can set all the constraints in Interface Builder. This was difficult in previous XCode-Releases since IB always tried to automatically adjust them if there was a problem. Constraints can be added by selecting the elements that you want to constrain (UIScrollView and UIDetailView) and then selecting the constraint from the menu. After adding it, you can edit it in the properties-pane. – patric.schenke Oct 01 '13 at 11:54
  • I can't do anything to UIView only to UIScrollView and UIContentView with constraints? Do i set the top-, bottom-, with the button that looks like: |-+-|? Do i have to do anything in code also? – KeVal Oct 01 '13 at 13:34
  • Sorry, please read the site-rules. We're not here to teach you or do your homework. Please read the documentation and watch the WWDC-videos on this topic. – patric.schenke Oct 01 '13 at 14:09
  • Yea sorry to ask that much, I wouldn't be so specific but NOTHING seems to work anymore (nothing that worked flawlessly on previous version of Xcode) – KeVal Oct 03 '13 at 12:44
  • As I said: previous versions of XCode automatically added/adjusted constraints for you. That made some things easier but others impossible - you had to do them in code. Now you have full control over your constraints. It takes a bit more effort but will eventually yield the results you want instead of those you can accept. – patric.schenke Oct 07 '13 at 08:38
2

I had a similar problem and i found relative simple solution similar to DJ S's from within Interface Builder using pure Autolayout without any code.

For proof-of-concept at first remove any constraint in View Controller to if see this works.

This is sample layout:

  • View (main view of my UIViewController)

    • Scroll View (UIScrollView)

      • Container View (UIView)

        • Content View (e.g. UIImageView)

A. Scroll View width/height should be smaller that Container View width/height

B. Container View should have some determinated width/height (may be explicit width/height )

C. Do Control-drag Container View to Scroll View and add only:

  1. Leading Space to Container
  2. Trailing Space to Container

D. Check out those two constraints and set "constant" value for both to 0

E. Run app and

vedrano
  • 2,961
  • 1
  • 28
  • 25
1

Because of the new iPhone 6 and 6+ screen sizes, I had to make a few tweaks to DJ S's solution.

The goal

Position a UITextView inside a UIScrollView, and also have 15 pt spaces from the left/right screen edges.

Views

1. Main View (main view of my UIViewController)
  2. Scroll View (UIScrollView)
     3. Container View (UIView)
       4. Text View (UITextView)

Solution

For the spaces, I added 15 pt horizontal trailing/leading spaces from UIScrollView->Main View. To make the UITextView's width relative to the screen width, I added an Equal Widths constraint from UITextView -> Main View and set the value to -30 (2 * the 15 pt horizontal space). Now, the UITextView's width will dynamically adjust for any screen size.

The UIScrollView should have Scrolling Enabled. The UITextView should not.

Rog182
  • 4,829
  • 1
  • 14
  • 4