Re: Auto layout semantics?
Re: Auto layout semantics?
- Subject: Re: Auto layout semantics?
- From: Fritz Anderson <email@hidden>
- Date: Thu, 15 Aug 2013 13:16:34 -0500
On 15 Aug 2013, at 11:33 AM, Izak van Langevelde <email@hidden> wrote:
> I wasted some time trying to use auto layout to maintain the layout of a form, to make sure that fields are horizontally resized with the form, while labels maintain their size. However, when two fields are sitting next to each other, having the same priority, only one of them resizes with the form. Is there any documentation around that specifies how layout constraints are resolved?
There is a lot that describes the process of resolving constraints, starting with <http://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/Articles/Introduction.html>. Assuming your have that information down, your problem may be that Xcode 4's Interface Builder is fighting you.
Most of what you need to do can be reasoned-through from two principles: Constraints on a view have to be sufficient to specify its size and placement so there is no more than one solution; and consistent, so they yield no less than one solution.
Interface Builder in Xcode 4 "helpfully" enforces sufficiency by automatically creating constraints according to the "making s*** up" algorithm*, and not letting you change or delete them. There's a menu at the lower-right that relieves the upstream and downstream effects so you can be free to adjust placements; and you can delete IB's constraints by first adding a sufficient constraint chain of your own.
* (The responsible engineers did a respectable job, but the result is opaque and frustrating. I know Dev Tools has made this a top priority.)
Do I understand correctly that you have a row in your form that looks like:
|--Label1-Field1--Label2-Field2 --|
? (Not intended to be a constraint-specification format.) And you want Label1 and Label2 to be of fixed (identical?) size, and Field1 and Field2 to have variable (equal?) size according to the width of the superview?
If I'm not correct, the rest is TL;DR. Caveat that I'm working off the top of my head on my lunch hour, and drawing suggestions from the same place Xc4 gets automatic constraints. This is "what I'd try next."
I'll comment only on the horizontal axis. I'm not going to comment on getting spacing and alignment from other elements in the view (like the rows above and below).
All the horizontal-spacing constraints should be of constant size, and 1000 priority.
The labels should have either numerically-constant widths, or you could turn up the priority on their horizontal compression resistance. The latter will mean that if a localization requires more or less room for the text, the label will expand accordingly but take up no more room than necessary. Consider an additional width constraint of ≥ some number.
Don't allow any placement constraints that aren't between immediate neighbors. It's easy to pick those up (and until the whole horizontal chain is solved, IB may insist on imposing them), but you aren't finished until duplicate or extraneous spacing constraints are gone. (Frequently one has to vary from this rule-of-thumb, but it's what I start from.)
That leaves the problem of the fields. If you are happy making them of equal size, your work is done; the whole chain is determined. If you know only minimum or maximum sizes, that isn't sufficient (and IB-Xc4 may force constraints of its own on you). If the min/max sizes are all you have, the chain is indeterminate, and when you resize the container, the change may be allocated to one, maybe to the other, there's no sure way to know in advance; whatever happens, the constraints you do have wouldn't be contradicted.
I don't know of a graphical way to set non-equal distributions of width changes. (Meaning, I think there is none, but I'm too weaselly to commit to it.) I think — I've never done this, and I don't have time to try — you can do it in code. Create an NSLayoutConstraint from one field to the next, on NSLayoutAttributeWidth, relation equal, but the multiplier and constant set up so that the first width is related to the second by:
width1 = multiplier * width2 + constant
Once you work out the proportions, the whole chain will be determined, and it should do what you want. Definitely set a minimum width on the smaller field, or it could be compressed to or below zero.
(An NSMutableLayoutConstraint would be _extremely_ helpful here. Radar in process.)
— F
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden