-
-
Notifications
You must be signed in to change notification settings - Fork 215
2. Layout
Width
view.width(100)
Height
view.height(100)
Size
view.size(100)
Constraining multiple views
equalSizes(image1, image2, image2)
equalWidths(field1, field2, field3, field4)
equalHeights(button1, button2)
Constraining a view to stay squared
view.heightEqualsWidth()
Horizontally
imageView.centerHorizontally()
imageView.centerHorizontally(20) //offset
Vertically
imageView.centerVertically()
imageView.centerVertically(20) //offset
On both axis
imageView.centerInContainer()
Horizontally
view.fillHorizontally()
view.fillHorizontally(m: 20) // padding
Vertically
view.fillVertically()
view.fillVertically(m: 20) // padding
All container
view.fillContainer()
view.fillContainer(20) // Padding
Horizontally
alignHorizontally(avatar,name,followButton)
Vertically
alignVertically(title,subtitle,text)
Tops
alignTops(title,subtitle,text)
Bottoms
alignBottoms(title,subtitle,text)
Rights
alignRights(title,subtitle,text)
Lefts
alignLefts(title,subtitle,text)
Align the center of one view with another one :
alignCenter(view1, with: view2)
In the example above of a follow Cell, here is how the layout code would look like :
|-avatar-15-name-20-followButton-|
alignHorizontally(avatar,name,followButton)
But |-avatar-15-name-20-followButton-|
actually returns the array of views!!! so we can write it in one single statement :
alignHorizontally(|-avatar-15-name-20-followButton-|)
🎉🎉🎉
The typical example of this is when we want to have a button on top of an image.
button.followEdges(imageView)
This is intended to look like Apple's visual format, so you should be very familiar with the syntax.
Stevia only removes the []
and the String.
Stick a label to the left of the screen
|label
With the default margin (8)
|-label
With a custom margin
|-42-label
Just to be very clear we want to emphasize that this is pure syntactic sugar.
This equivalent of the following using the chainable api :
label.left(42)
Which in turn will create Native Autolayout constraints :
label.superview?.addConstraint(
NSLayoutConstraint(
item: label,
attribute:.Left,
relatedBy: .Equal,
toItem: label.superview!,
attribute:.Left,
multiplier: 1,
constant: 42
)
)
Combine all at once.
|-avatar-15-name-20-followButton-|
avatar.top(50)
==
layout(
50,
avatar
)
While using layout
for a single element might seem a bit overkill, it really shines when combined with horizontal layout.
Then we have the full layout in one place (hence the name).
layout(
50,
|-15-avatar.size(60)
)
The avatar is 50px from the top with a left margin of 15px and a size of 60px
Another great example is the login view, representable in one single statement !
layout(
100,
|-email-| ~ 80,
8,
|-password-| ~ 80,
"",
|login| ~ 80,
0
)
In case you wonder ~
operator == .height(x)
, it's just more readable in a layout statement that way.
The avatar example above could've been written that way using the chainable api :
avatar.top(50).left(15).size(50)
Using layout
is just clearer in most of the cases but it's yours to choose which way you prefer :)
Flexible margins can be used exactly like regular margins:
view.top(<=5)
view.left(>=20)
view.bottom(<=10)
view.right(<=15)
view.width(>=45)
view.height(<=100)
layout(
5,
|-label-(>=5)-|,
>=20,
separator ~ (>=10),
0
)
view.top(5%)
view.left(20%)
view.bottom(10%)
view.right(15%)
view.width(45%)
view.height(100%)
view.Height == 47 % button.Width
Tricky layout cases can be described as equations.
button.CenterY == avatar.Bottom - 4
label.Width <= button.Width * 3
label.Height == (button.Width / 7) + 3
button.Left >= image.Right - 20
image.Height >= 100
view.Top == 10
The result is a native NSLayoutConstraint. So you can modify priority like so :
(label.Width == button.Width * 3).priority = 1000 // Making this a required constraint.
There is no special Stevia api for priorities. In order to set them, you need to use the good'ol standard api :) By default, Stevia constraints are created with a priority of 751.
let c = NSLayoutConstraint(item: v, attribute: .Top, relatedBy: .Equal, toItem: v, attribute: .Top, multiplier: 1, constant: 0)
c.priority = 1000 // Make a constraint `required`
addConstraint(c)
(label.Width == button.Width * 3).priority = 1000 // Making this a required constraint.
let constraint == view.Height = 50 % Height
// later..
constraint.priority = 750