1
votes

I have a problem with AutoLayout which is causing me a real headache. I have a scrollview & container view set up in a .xib using Autolayout. I need to dynamically add subviews to the container view and am trying to get them to play nice with Auto Layout. This is not going well...

Here is a picture of what I am trying to accomplish: enter image description here

So the Scroll View and Container Layer are set up in a xib already with autolayout and view 1-3 I am trying to add programatically. My first approach was:

[containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-20-[viewOne]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(viewOne)]]

which resulted in:

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. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)

(
      "<NSLayoutConstraint:0x9d84de0 H:|-(20)-[UIView:0x9d922e0]   (Names: '|':UIView:0x9d91fb0 )>",
      "<NSAutoresizingMaskLayoutConstraint:0x9d9fe90 h=--& v=--& UIView:0x9d922e0.midX ==>"
)

I have also tried using constraintWithItem:attribute:relatedBy:toItem:attribute:multiplier:constant but am struggling to get it to work the way I want. Am I doing something fundamentally wrong?

Stephen

3
how do you create viewOne? are you doing translatesAutoresizingMaskIntoConstraints = NO on viewOne?darren102
Could you please provide us more info about your subviews?brianLikeApple
viewOne is created using [UIView alloc] init]. I have also tried [UIView alloc] initWithFrame:CGRectNull]Stephen Groom
The subviews will ultimately get more complex but for now they are just empty views. I have not yet tried translatesAutoResizingMaskIntoConstraints but will try now, tyStephen Groom

3 Answers

1
votes
  1. Make sure all your subviews' translatesAutoresizingMaskIntoConstraints to NO.
  2. Make sure don't set frame to your subviews, because AutoLayout is talking about views' relationships not its frame.
  3. Make sure you have sufficient constraints that system is not confused.
2
votes

Another possible reason: using a multiplier of 0 instead of 1...

0
votes

I had exactly the same issue (so frustrating, but the debugger provided a good hint.) In my case I was creating a super-view constraint prior to having added my sub-view to the super-view. It seems like this should work, because there is no actual super-view object passed to the constraint builder function. Here is the before and after (mine is swift, hopefully you can follow):

Broken Version:

let v0 = UILabel(frame: CGRect(x: 100, y: 50, width: 200, height: 20))
v0.text = "Hello"
let v1 = UILabel(frame: CGRect(x: 100, y: 100, width: 200, height: 20))
v1.text = "World"


let c0 : AnyObject[]! = NSLayoutConstraint.constraintsWithVisualFormat(
    "V:|-20-[top]-10-[bottom]",
    options: NSLayoutFormatOptions.fromMask(0),
    metrics: nil,
    views: ["top":v0, "bottom":v1])

mainView.autoresizesSubviews = true

for v in [v0, v1, mainView]
{
    mainView.setTranslatesAutoresizingMaskIntoConstraints(false)
}

for v in [v0, v1]
{
    mainView.addSubview(v)
}


mainView.addConstraints(c0)

Fixed Version:

let v0 = UILabel(frame: CGRect(x: 100, y: 50, width: 200, height: 20))
v0.text = "Hello"
let v1 = UILabel(frame: CGRect(x: 100, y: 100, width: 200, height: 20))
v1.text = "World"

mainView.autoresizesSubviews = true

for v in [v0, v1, mainView]
{
    mainView.setTranslatesAutoresizingMaskIntoConstraints(false)
}

for v in [v0, v1]
{
    mainView.addSubview(v)
}


let c0 : AnyObject[]! = NSLayoutConstraint.constraintsWithVisualFormat(
    "V:|-20-[top]-10-[bottom]",
    options: NSLayoutFormatOptions.fromMask(0),
    metrics: nil,
    views: ["top":v0, "bottom":v1])

mainView.addConstraints(c0)