Last active
April 16, 2019 07:33
-
-
Save marty-suzuki/79b7a39edfbc17d9dac4ee8cf9ae2091 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
// - MRAK: Constraint | |
struct Constraint { | |
private let _constraint: (UIView, UIView) -> NSLayoutConstraint | |
init(_ constraint: @escaping (UIView, UIView) -> NSLayoutConstraint) { | |
self._constraint = constraint | |
} | |
func constraint(_ view1: UIView, _ view2: UIView) -> NSLayoutConstraint { | |
return _constraint(view1, view2) | |
} | |
} | |
extension Constraint { | |
static func equal<L, Axis>(_ to: KeyPath<UIView, L>, constant: CGFloat = 0, priority: UILayoutPriority? = nil) -> Constraint where L: NSLayoutAnchor<Axis> { | |
return equal(to, to, constant: constant, priority: priority) | |
} | |
static func equal<L, Axis>(_ from: KeyPath<UIView, L>, _ to: KeyPath<UIView, L>, constant: CGFloat = 0, priority: UILayoutPriority? = nil) -> Constraint where L: NSLayoutAnchor<Axis> { | |
return Constraint({ view1, view2 in | |
let constraint = view1[keyPath: from].constraint(equalTo: view2[keyPath: to], constant: constant) | |
if let priority = priority { | |
constraint.priority = priority | |
} | |
return constraint | |
}) | |
} | |
} | |
extension Constraint { | |
static func equal<L, Axis>(_ to: Anchor<L>, constant: CGFloat = 0, priority: UILayoutPriority? = nil) -> Constraint where L: NSLayoutAnchor<Axis> { | |
return equal(to, to, constant: constant, priority: priority) | |
} | |
static func equal<L, Axis>(_ from: Anchor<L>, _ to: Anchor<L>, constant: CGFloat = 0, priority: UILayoutPriority? = nil) -> Constraint where L: NSLayoutAnchor<Axis> { | |
return Constraint({ view1, view2 in | |
let constraint = view1[keyPath: from.keyPath].constraint(equalTo: view2[keyPath: to.keyPath], constant: constant) | |
if let priority = priority { | |
constraint.priority = priority | |
} | |
return constraint | |
}) | |
} | |
} | |
extension Array where Element == Constraint { | |
static func edges(_ insets: UIEdgeInsets = .zero, priority: UILayoutPriority? = nil) -> [Constraint] { | |
return [.equal(\.topAnchor, constant: insets.top, priority: priority), | |
.equal(\.leftAnchor, constant: insets.left, priority: priority), | |
.equal(\.rightAnchor, constant: insets.right, priority: priority), | |
.equal(\.bottomAnchor, constant: insets.bottom, priority: priority)] | |
} | |
} | |
// - MRAK: UIView Extension | |
extension UIView { | |
func addSubview(_ subview: UIView, constraints: [Constraint]) { | |
subview.translatesAutoresizingMaskIntoConstraints = false | |
addSubview(subview) | |
addConstraints(constraints.map { $0.constraint(subview, self) }) | |
} | |
func addConstraint(_ constraint: Constraint, to other: UIView) { | |
addConstraints([constraint], to: other) | |
} | |
func addConstraints(_ constraints: [Constraint], to other: UIView) { | |
addConstraints(constraints.map { $0.constraint(other, self) }) | |
} | |
} | |
// - MARK: - Anchor | |
protocol AnchorProxy {} | |
struct Anchor<LayoutAnchor>: AnchorProxy { | |
let keyPath: KeyPath<UIView, LayoutAnchor> | |
} | |
extension AnchorProxy { | |
static var top: Anchor<NSLayoutYAxisAnchor> { | |
return .init(keyPath: \.topAnchor) | |
} | |
static var bottom: Anchor<NSLayoutYAxisAnchor> { | |
return .init(keyPath: \.bottomAnchor) | |
} | |
static var leading: Anchor<NSLayoutXAxisAnchor> { | |
return .init(keyPath: \.leadingAnchor) | |
} | |
static var trailing: Anchor<NSLayoutXAxisAnchor> { | |
return .init(keyPath: \.trailingAnchor) | |
} | |
} | |
// - MARK: main | |
func main() { | |
let view1 = UIView() | |
let view2 = UIView() | |
let view3 = UIView() | |
view1.addSubview(view2, constraints: .edges()) | |
view1.addSubview(view3, constraints: [.equal(\.topAnchor)]) | |
view1.addSubview(view3, constraints: [.equal(.bottom)]) | |
view2.addConstraints([.equal(\.leftAnchor, \.rightAnchor)], to: view3) | |
} | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment