Search code examples
iosswiftuiscrollviewautolayoutconstraints

Scrollview working by breaking constraint


I have a UIViewController containing a scrollView: the scrollView is pinned (0,0,0,0) to the superview.

The scrollView contains a Content View with the following constraints set:

enter image description here

Inside this view, I put a square image view: it is pinned this way and its height equals the width of its superview.

enter image description here

Anything I described until now is done manually in the storyboard.

Then, using a simple button (so, after viewDidLoad, viewDidLayoutSubviews, etc.), I execute the following function (that 375 is currently hard-coded, but it is the heigth of the image view frame on the device I’m using for testing purposes):

var startH = 0

for i in 0...10 {

let v = UIView(frame: CGRect(x: 0, y: 375+startH, width: 375, height: startH))
    v.backgroundColor = .random
    contentView.addSubview(v)
    startH += 100
}

let scrollerLayoutGuide = scrollView.contentLayoutGuide
scrollerLayoutGuide.heightAnchor.constraint(equalToConstant: CGFloat(startH+375)).isActive = true
scrollView.contentSize = contentView.frame.size

This should (and actually it does) create 11 views under the imageView, inside the contentView of the scrollView.

Problem is when I execute this function I get the following error:

[LayoutConstraints] Unable to simultaneously satisfy constraints.   
Probably at least one of the constraints in the following list is one you don't want.   
Try this:       (1) look at each constraint and try to figure out which you don't expect;       (2) find the code that added the unwanted constraint or constraints and fix it.  (
    "<NSLayoutConstraint:0x6000019d7d40 UIView:0x7fe66940aa30.height == UIScrollView:0x7fe66985b400.height   (active)>",
    "<NSLayoutConstraint:0x6000019d7d90 V:|-(0)-[UIView:0x7fe66940aa30]   (active, names: '|':UIScrollView:0x7fe66985b400 )>",
    "<NSLayoutConstraint:0x6000019d7de0 V:[UIView:0x7fe66940aa30]-(0)-|   (active, names: '|':UIScrollView:0x7fe66985b400 )>",
    "<NSLayoutConstraint:0x6000019e4690 UILayoutGuide:0x6000003c81c0'UIViewSafeAreaLayoutGuide'.bottom == UIScrollView:0x7fe66985b400.bottom   (active)>",
    "<NSLayoutConstraint:0x6000019e4730 UIScrollView:0x7fe66985b400.top == UILayoutGuide:0x6000003c81c0'UIViewSafeAreaLayoutGuide'.top   (active)>",
    "<NSLayoutConstraint:0x6000019e11d0 _UIScrollViewLayoutGuide:0x6000003ac1c0'UIScrollView-contentLayoutGuide'.height
== 1475   (active)>",
    "<NSLayoutConstraint:0x6000019e9540 'UIView-Encapsulated-Layout-Height' UIView:0x7fe66950bdb0.height == 667   (active)>",
    "<NSLayoutConstraint:0x6000019e45f0 'UIViewSafeAreaLayoutGuide-bottom' V:[UILayoutGuide:0x6000003c81c0'UIViewSafeAreaLayoutGuide']-(0)-|   (active, names: '|':UIView:0x7fe66950bdb0 )>",
    "<NSLayoutConstraint:0x6000019e4550 'UIViewSafeAreaLayoutGuide-top' V:|-(20)-[UILayoutGuide:0x6000003c81c0'UIViewSafeAreaLayoutGuide']   (active, names: '|':UIView:0x7fe66950bdb0 )>" )

Will attempt to recover by breaking constraint  <NSLayoutConstraint:0x6000019d7de0 V:[UIView:0x7fe66940aa30]-(0)-|   (active, names: '|':UIScrollView:0x7fe66985b400 )>

Problem is I can't understand what constraint is causing this issue and, most of all, why. Could you help me?


Solution

  • There is conflict between your constraints with contentView

    1. There is Top, bottom, leading, trailing with the scrollview 2. Fixed height and fixed width constraint of contentView

    These two will conflict each other as OS will not be sure which constraint to fulfil. As a solution reduce the priority of height and width constraint so that the more priority is given to the constraint with respect to the scrollView.

    For more details please follow below tutorial How to configure a UIScrollView with Auto Layout