1
votes

I've come across some odd behaviour when building a basic UIScrollView example with Auto Layout.

In the Storyboard editor I added a UIScrollView as a child of the default UIView and within that I have added a new UIView and named it contentView:

View

--scrollView

----contentView

I added some labels and text boxes to the contentView and set their constraints to the parent container (contentView).

I also set constraints on contentView to the UIScrollView, the UIScrollView to it's parent and finally set contentView to use the same height & width as the top level UIView. After adding the constraints all errors or warnings about missing constraints are gone and the screen looks exactly how I want it in the Storyboard editor.

For ease of troubleshooting I coloured the primary View blue, the UIScrollView yellow and the contentView green.

When I run the app on the simulator or a real phone the text fields are shrunk down instead of being 200 wide, label 3 and its text box are missing (off screen most likely) and the screen is yellow indicating the UIScrollView is being shown. As soon as I rotate the screen everything looks exactly like it should:

Gifycat image link as I can't post images yet

Printing out the widths of the frames:

  • View width: 320.0
  • scrollView width: 240.0
  • contentView width: 240.0

I've replicated this behaviour in Swift 1 & 2 using Xcode 6.4 and 7.0 beta 4.

1
I think you need constraints on the UIScrollView to it's parent viewFred Faust
Apologies, I missed that part out of the description, will edit it in now as the UIScrollview does have constraints to it's parentPete
It's really a matter of how you set the constraints, did you constrain width & horizontal constraints? Sometimes it's easiest to start with the least amount and work your way "up"Fred Faust
@thefredelement for the UIScrollView I set constraints on Trailing Space, Leading Space, Bottom Space and Top space to it's parent. For contentView I set the same to it's parent (scrollView) but also set it's width and height to be equal to that of the top Level ViewPete
The view inside of your scrollview needs to be defined so the scroll view knows what it has to scroll. Which would be the UIView that then contains your text fields. I think your last UIView is a bit redundant and if you don't need it I would suggest placing the elements directly into the UIScrollView, they will need height & width constraints thoughFred Faust

1 Answers

0
votes

So I managed to fix the child UIView by overriding the viewDidLayoutSubviews() function in viewController.swift

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()

        let widthConstraint = NSLayoutConstraint(item: contentView, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: parentView.frame.width)

        contentView.addConstraint(widthConstraint)

        let heightConstraint = NSLayoutConstraint(item: contentView, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: parentView.frame.height)
        contentView.addConstraint(heightConstraint)
    }

parentView being an outlet for the top level UIView and contentView an outlet for the child UIView within the UIScrollView.