- Requirements:
var views: [String: Any]
var metrics: [String: Any]
- Protocol Extension methods
H(String) { // adjust layout priority here }
V(String) { // adjust layout priority here }
J(NSLayoutConstraint, UILayoutPriority=.required)
G([NSLayoutConstraint])
- Superclass
ArielViewController
ArielView
Here's an example:
class ViewController : ArielViewController {
let buttonSignIn = UIButton()
let buttonRegister = UIButton()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(buttonSignIn)
view.addSubview(buttonRegister)
// setTitle, setTitleColor...
H("|-30-[buttonSignIn]-30-|")
H("|-20-[buttonRegister]-20-|")
V("|-80-[buttonSignIn]-20-[buttonRegister]")
}
}
With Apple's Auto Layout, the code would look like this:
// In viewDidLoad
buttonSignIn.translatesAutoresizingMaskIntoConstraints = false
buttonRegister.translatesAutoresizingMaskIntoConstraints = false
let views: [String: Any] =
["buttonSignIn": buttonSignIn, "buttonRegister": buttonRegister]
NSLayoutConstraint.activate(
NSLayoutConstraint.constraints(withVisualFormat: "H:|-30-[buttonSignIn]-30-|", metrics: nil, views: views))
NSLayoutConstraint.activate(
NSLayoutConstraint.constraints(withVisualFormat: "H:|-20-[buttonRegister]-20-|", metrics: nil, views: views))
NSLayoutConstraint.activate(
NSLayoutConstraint.constraints(withVisualFormat: "V:|-80-[buttonSignIn]-20-[buttonRegister]", metrics: nil, views: views))
precedencegroup LayoutPriorityGroup {
associativity: left
}
infix operator |> : LayoutPriorityGroup
@discardableResult
public func |>(lhs: UIView, rhs: UIView) -> UIView{
lhs.setContentHuggingPriority(UILayoutPriority(rawValue: rhs.contentHuggingPriority(for: .horizontal).rawValue-1), for: .horizontal)
return rhs
}
infix operator <| : LayoutPriorityGroup
@discardableResult
public func <|(lhs: UIView, rhs: UIView) -> UIView {
lhs.setContentHuggingPriority(UILayoutPriority(rawValue: rhs.contentHuggingPriority(for: .horizontal).rawValue+1), for: .horizontal)
return rhs
}
Example,
H("|-20-[labelName]-20-[fieldName]-10-[btnCheck]-20-|")
{ labelName <| fieldName |> btnCheck } // line 2
-
Align: Same attributes of two items.
align(_ attribute: NSLayoutAttribute, offset:CGFloat, with: UIView)
-
Match: Two attributes on same axis(but not identical) of two items.
match(_ attribute: NSLayoutAttribute, offset: CGFloat, with: (UIView, NSLayoutAttribute))
-
Scale: Width or height attributes relation between two items.
scale(_ attribute: NSLayoutAttribute, by multiplier: CGFloat, to: (UIView, NSLayoutAttribute))
-
Aspect: items own width-height ratio.
aspect(ratio: CGFloat)
-
Set: width or height to constant on item.
set(_ attribute: NSLayoutAttribute, to constant: CGFloat)
- center(in: UIView)
- edges(equal: UIView, insets: UIEdgeInsets)
-
The Signature
stack(views: [UIView], margin: CGFloat = 0, padding: CGFloat = 0, on axis: UILayoutConstraintAxis) -> (CGFloat...) -> [NSLayoutConstraint]
-
The
CGFloat...
// to stack subviews equally view.stack(view.subviews, on: .vertical) // to stack subviews based on proportions view.stack(view.subviews, on: .vertical)(0.1, 0.2, 0.3) // Notices: // If proportions' count less than subviews' count, the remaining subviews divided equally with total of 0.4 (1-0.1-0.2-0.3) // If proportions' count greater than subviews' count, the extras arguments is not used.
J(btnSignIn.align(.centerY, with: btnRegister))
J(btnSignIn.match(.leading, with: (viewLogo, .centerX)))
G(viewLogo.edges(equal: view, insets: .zero))
G(btnSignIn.center(in: containerView))