Skip to content

Instantly share code, notes, and snippets.

addSubview(redView) {
$0.edges(20).equalToSuperview()
}
extension ConstraintBuilding {
public func edges(_ constant: CGFloat = 0) -> ConstraintBuilder {
top(constant).leading(constant).trailing(-constant).bottom(-constant)
}
}
addSubview(redView) {
$0.top(20).leading(20).trailing(-20).bottom(-20).equalToSuperview()
}
public struct ConstraintBuilder: ConstraintBuilding {
public let anchorable: Anchorable
private let superviewBlock: (NSLayoutConstraint.Relation) -> [NSLayoutConstraint]
public func build(_ anchor: Anchor, constant: CGFloat, multiplier: CGFloat) -> ConstraintBuilder {
combine(with: anchorable.build(anchor, constant: constant, multiplier: multiplier))
}
public func equalToSuperview() -> [NSLayoutConstraint] {
superviewBlock(.equal)
public protocol ConstraintBuilding {
var anchorable: Anchorable { get }
func build(
_ anchor: Anchor,
constant: CGFloat,
multiplier: CGFloat
) -> ConstraintBuilder
}
extension ConstraintBuilding {
public protocol Anchorable: AnyObject, ConstraintBuilding {}
extension Anchorable {
func anchor(_ attribute: NSLayoutConstraint.Attribute) -> Anchor {
.init(anchorable: self, attribute: attribute)
}
public var leading: Anchor { anchor(.leading) }
public var trailing: Anchor { anchor(.trailing) }
public var top: Anchor { anchor(.top) }
public var bottom: Anchor { anchor(.bottom) }
addSubview(redView) {
$0.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 20)
$0.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -20)
$0.topAnchor.constraint(equalTo: topAnchor, constant: 20)
$0.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -20)
}
@resultBuilder
public enum AutoLayoutBuilder {
public static func buildBlock(_ components: Constrainable...) -> [NSLayoutConstraint] {
components.flatMap(\.constraints)
}
}
extension UIView {
@discardableResult public func addSubview<View: UIView>(_ view: View, @AutoLayoutBuilder with makeConstraints: (View) -> [Constrainable]) -> [NSLayoutConstraint] {
public protocol Constrainable {
var constraints: [NSLayoutConstraint] { get }
}
extension NSLayoutConstraint: Constrainable {
public var constraints: [NSLayoutConstraint] { [self] }
}
extension Array: Constrainable where Element == NSLayoutConstraint {
public var constraints: [NSLayoutConstraint] { self }
addSubviews(leftView, middleView, rightView) { leftView, middleView, rightView in
leftView.verticalEdges.leading == Superview()
middleView.verticalEdges == Superview()
middleView.leading(20) >= leftView.trailing
middleView.trailing(-20) <= rightView.leading
rightView.verticalEdges.trailing == Superview()
}