Skip to content

Instantly share code, notes, and snippets.

@marty-suzuki
Created October 1, 2019 14:33
Show Gist options
  • Save marty-suzuki/c0ce1081d88ad5947397598dddfb4be0 to your computer and use it in GitHub Desktop.
Save marty-suzuki/c0ce1081d88ad5947397598dddfb4be0 to your computer and use it in GitHub Desktop.
import Foundation
import UIKit
@_functionBuilder struct ConstraintBuilder {
static func buildBlock<T, U>(_ from: NSLayoutAnchor<T>,
_ relation: Relation<U>,
_ to: NSLayoutAnchor<T>) -> NSLayoutConstraint {
return U.constraint(from: from, to: to, constant: relation.constant)
}
}
func constraint(@ConstraintBuilder block: () -> NSLayoutConstraint) -> NSLayoutConstraint {
block()
}
protocol RelationTrait {
static func constraint<T>(from: NSLayoutAnchor<T>,
to: NSLayoutAnchor<T>,
constant: CGFloat) -> NSLayoutConstraint
}
enum Relatons {
enum Equal: RelationTrait {
static func constraint<T>(from: NSLayoutAnchor<T>,
to: NSLayoutAnchor<T>,
constant: CGFloat) -> NSLayoutConstraint {
from.constraint(equalTo: to, constant: constant)
}
}
enum LessThanOrEqual: RelationTrait {
static func constraint<T>(from: NSLayoutAnchor<T>,
to: NSLayoutAnchor<T>,
constant: CGFloat) -> NSLayoutConstraint {
from.constraint(lessThanOrEqualTo: to, constant: constant)
}
}
enum GreaterThanOrEqual: RelationTrait {
static func constraint<T>(from: NSLayoutAnchor<T>,
to: NSLayoutAnchor<T>,
constant: CGFloat) -> NSLayoutConstraint {
from.constraint(greaterThanOrEqualTo: to, constant: constant)
}
}
}
struct Relation<Trait: RelationTrait> {
let constant: CGFloat
init(_ constant: CGFloat = 0) {
self.constant = constant
}
}
typealias Equal = Relation<Relatons.Equal>
typealias LessThanOrEqual = Relation<Relatons.LessThanOrEqual>
typealias GreaterThanOrEqual = Relation<Relatons.GreaterThanOrEqual>
let view1 = UIView()
let view2 = UIView()
let c1: NSLayoutConstraint = constraint {
view1.bottomAnchor
Equal(10)
view2.topAnchor
}
let c2: NSLayoutConstraint = constraint {
view1.leadingAnchor
GreaterThanOrEqual(-20)
view2.trailingAnchor
}
let c3: NSLayoutConstraint = constraint {
view1.leadingAnchor
GreaterThanOrEqual()
view2.trailingAnchor
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment