Skip to content
S4cha edited this page Jan 23, 2017 · 8 revisions

Sizing

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()

Centering

Horizontally

imageView.centerHorizontally()
imageView.centerHorizontally(20) //offset

Vertically

imageView.centerVertically()
imageView.centerVertically(20) //offset

On both axis

imageView.centerInContainer()

Filling

Horizontally

view.fillHorizontally()
view.fillHorizontally(m: 20) // padding

Vertically

view.fillVertically()
view.fillVertically(m: 20) // padding

All container

view.fillContainer()
view.fillContainer(20) // Padding

Aligning

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-|)

🎉🎉🎉

Following Another View

The typical example of this is when we want to have a button on top of an image.

button.followEdges(imageView)

Horizontal layout

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-|

Vertical layout

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.

Chainable Api

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

Flexible margins can be used exactly like regular margins:

With chainable Api

view.top(<=5)
view.left(>=20)
view.bottom(<=10)
view.right(<=15)
view.width(>=45)
view.height(<=100)

In layout calls

layout(
    5,
    |-label-(>=5)-|,
    >=20,
    separator ~ (>=10),
    0
)

Percentage-Based Layout

view.top(5%)
view.left(20%)
view.bottom(10%)
view.right(15%)
view.width(45%)
view.height(100%)
view.Height == 47 % button.Width

Equations

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.

Priorities

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