1

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

4
  • 2
    how do you create viewOne? are you doing translatesAutoresizingMaskIntoConstraints = NO on viewOne? Commented Dec 17, 2013 at 17:02
  • Could you please provide us more info about your subviews? Commented Dec 17, 2013 at 17:15
  • viewOne is created using [UIView alloc] init]. I have also tried [UIView alloc] initWithFrame:CGRectNull] Commented Dec 18, 2013 at 11:49
  • 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, ty Commented Dec 18, 2013 at 11:50

3 Answers 3

2

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

Sign up to request clarification or add additional context in comments.

1 Comment

Sometimes it's the things we don't expect - such as this!
1
  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.

1 Comment

Thanks. The main problem was translatesAutoResizingMaskIntoConstraints and a little bit of carelessness when writing my visual format language.
0

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)

1 Comment

Welcome to StackOverflow! While this may answer the question in a basic sense, could you elaborate a bit more as to why it works? This is arguably a code only answer (since the code itself is not explained), which are discouraged.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.