I am trying to use the new Auto Layout in Lion because it seems quite nice. But I can not find good information about how to do things. For example:
I have two labels:>
I've found another way to do this. This methodology can be applied anywhere, has no scaling problems; and handles the margins as well. And you don't need 3rd party things for it.
First, dont use this layout:
V:|-?-[Label1]-10-[Label2]-10-|
H:|-?-[Label1]-?-|
H:|-20-[Label2]-20-|
Use these instead:
("|" is the real (outer) container)
V:|-?-[Label1]-0-[Label2HideableMarginContainer]-0-|
H:|-?-[Label1]-?-|
H:|-0-[Label2HideableMarginContainer]-0-|
("|" is Label2HideableMarginContainer)
V:|-10-[Label2]-10-|
H:|-20-[Label2]-20-|
So what have we done now? Label2
is not directly used in the layout; it's placed into a Margin-Container
. That container is used as a proxy of Label2
, with 0 margins in the layout. The real margins are put inside of the Margin-Container
.
Now we can hide Label2
with:
Hidden
to YES
on itAND
Top
, Bottom
, Leading
and Trailing
constraints. So seek them out, than set Active
to NO
on them. This will cause the Margin-Container
to have a Frame Size
of (0,0); because it does have subview(s); but there aren't any (active) layout constraints which anchors those subviews to it.Maybe a bit complex, but you only have to develop it once. All the logic can be put into a separate place, and be reused every time you need to hide smg.
Here is C# Xamarin code how to seek those constraints which anchors the subview(s) to the inner edges of the Margin-Container
view:
public List SubConstraints { get; private set; }
private void ReadSubContraints()
{
var constraints = View.Constraints; // View: the Margin-Container NSView
if(constraints?.Any() ?? false)
{
SubConstraints = constraints.Where((NSLayoutConstraint c) => {
var predicate =
c.FirstAttribute == NSLayoutAttribute.Top ||
c.FirstAttribute == NSLayoutAttribute.Bottom ||
c.FirstAttribute == NSLayoutAttribute.Leading ||
c.FirstAttribute == NSLayoutAttribute.Trailing;
predicate &= ViewAndSubviews.Contains(c.FirstItem); // ViewAndSubviews: The View and View.Subviews
predicate &= ViewAndSubviews.Contains(c.SecondItem);
return predicate;
}).ToList();
}
}