1

I'm trying to set a constraint where the width of two views should fill the screen. If I change the width of one view, the other view should change accordingly:

[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-8-[view1]-8-[view2]-8-|" options:0 metrics:nil views:views]];

I think this is rather simple, but the code seems to ignore the size of view2. view1 keeps getting the entire width of the screen and setting the frame of view2 doesn't affect the width of view1.

What am I missing?

jscs
  • 63,694
  • 13
  • 151
  • 195
Nam
  • 1,856
  • 2
  • 13
  • 18

1 Answers1

2

Assign a minimum size constraint to view2 as well, or "0 width" will be a valid solution to the constraints.

[NSLayoutConstraint activateConstraints:
    [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-8-[view1(>=minSize)]-8-[view2(>=minSize)]-8-|" 
                                            options:0 
                                            metrics:@{@"minSize" : @50} 
                                              views:views]];

Also, don't use addConstraints: anymore (iOS 8+). Use -[NSLayoutConstraint setActive:] or +[NSLayoutConstraint activateConstraints:]

As for changing view2's size, you can't set views' frames directly when you're using Auto Layout. The value will be overwritten on the next layout pass. You should create an explicit width constraint for the view:

[NSLayoutConstraint constraintWithItem:view2
                             attribute:NSLayoutAttributeWidth
                             relatedBy:NSLayoutRelationEqual
                                toItem:nil
                             attribute:NSLayoutAttributeNotAnAttribute
                            multiplier:1.0
                              constant:120];

and then adjust that constraint's constant when you need to change the view's size.

jscs
  • 63,694
  • 13
  • 151
  • 195
  • Thanks for your tip. This increases the size of view2 but nothing happens when I set the frame width of view2. It is like view1 har precedence. Btw, I need to support iOS7. – Nam Nov 26 '15 at 06:32
  • 2
    Are you trying to set frames directly, or are you adding a width constraint? Doing the former is ineffectual when you are using Auto Layout; that's kind of the point of Auto Layout. – jscs Nov 26 '15 at 06:34
  • I'm trying to set constraints so that if my view2 changes, view1 should change accordingly. Am I misusing the Auto Layout? – Nam Nov 26 '15 at 06:36
  • Under what circumstances are the views' widths changing? – jscs Nov 26 '15 at 06:37
  • I would suggest you constraint the leading edge of view1 to the leading edge of the containing view, the trailing edge of view2 to the trailing edge (or margin) of the containing view and the trailing edge of view1 to leading edge of view2 and then add a width constraint to view2. Now as you adjust the `constant` of that width constraint the two views will adjust their widths accordingly – Paulw11 Nov 26 '15 at 06:38
  • view1 is a UISearchBar. I want to change the size of it when the user is beginning a text edit. – Nam Nov 26 '15 at 06:38
  • And what means are you using to accomplish that, @Nam? – jscs Nov 26 '15 at 06:39
  • @JoshCaswell, not sure what "means" you're asking for? – Nam Nov 26 '15 at 06:41
  • How are you changing the views' sizes? @Nam – jscs Nov 26 '15 at 06:42
  • @JoshCaswell Im just writing `view2.frame = CGRectMake(x,y,w,h)` – Nam Nov 26 '15 at 06:50
  • Right, so, like I said, @Nam, use a width constraint, not direct frame setting. – jscs Nov 26 '15 at 06:51
  • @JoshCaswell Ah ok. Can you post a sample where I can change the width with a constraint? – Nam Nov 26 '15 at 06:54
  • @Paulw11 Thanks. I think Josh is suggesting the same and I need a sample to fully understand it – Nam Nov 26 '15 at 06:56
  • @JoshCaswell Great thanks! My idea was right, but setting the frame directly instead of the width constraint was wrong. – Nam Nov 26 '15 at 07:00
  • Glad I could help, @Nam. – jscs Nov 26 '15 at 07:01
  • 1
    See the answer here - http://stackoverflow.com/questions/12622424/how-do-i-animate-constraint-changes for code to animate the constraint change, so you can have your views resize with a nice animation – Paulw11 Nov 26 '15 at 07:08