Created
September 22, 2016 19:03
-
-
Save zhigang1992/4247751d4e09c5884d9fd5abcd393ca7 to your computer and use it in GitHub Desktop.
This file contains 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 | |
precedencegroup PipingPrecedence { | |
associativity: left | |
higherThan: LogicalConjunctionPrecedence | |
} | |
infix operator |> : PipingPrecedence | |
func |><A,B>(a:A, function: (A)->B) -> B { | |
return function(a) | |
} | |
struct ConstraintConfig { | |
let relation: NSLayoutRelation | |
let constant: CGFloat | |
let priority: UILayoutPriority | |
let activate: Bool | |
init ( | |
relation: NSLayoutRelation = .equal, | |
constant: CGFloat = 0.0, | |
priority: UILayoutPriority = UILayoutPriorityRequired, | |
activate: Bool = true | |
) { | |
self.relation = relation | |
self.constant = constant | |
self.priority = priority | |
self.activate = activate | |
} | |
static let defaultConfig = ConstraintConfig() | |
func config(constraint: NSLayoutConstraint) -> NSLayoutConstraint { | |
constraint.constant = self.constant | |
constraint.priority = self.priority | |
constraint.isActive = self.activate | |
return constraint | |
} | |
} | |
struct Edge { | |
static let top: (UIView) -> NSLayoutYAxisAnchor = { $0.topAnchor } | |
static let bottom: (UIView) -> NSLayoutYAxisAnchor = { $0.bottomAnchor } | |
static let leading: (UIView) -> NSLayoutXAxisAnchor = { $0.leadingAnchor } | |
static let trailing: (UIView) -> NSLayoutXAxisAnchor = { $0.trailingAnchor } | |
static let centerX: (UIView) -> NSLayoutXAxisAnchor = { $0.centerXAnchor } | |
static let centerY: (UIView) -> NSLayoutYAxisAnchor = { $0.centerYAnchor } | |
static let topGuide: (UIViewController) -> NSLayoutYAxisAnchor = { | |
$0.topLayoutGuide.bottomAnchor | |
} | |
static let width: (UIView) -> NSLayoutDimension = { $0.widthAnchor } | |
static let height: (UIView) -> NSLayoutDimension = { $0.heightAnchor } | |
} | |
enum EdgeToPin { | |
case leading(ConstraintConfig) | |
case trailing(ConstraintConfig) | |
case top(ConstraintConfig) | |
case bottom(ConstraintConfig) | |
static let all:[EdgeToPin] = [ | |
.leading(.defaultConfig), | |
.trailing(.defaultConfig), | |
.top(.defaultConfig), | |
.bottom(.defaultConfig) | |
] | |
} | |
struct AnchorMan { | |
static func pin<U, V, T: AnyObject>( | |
anchor: (U) -> NSLayoutAnchor<T>, | |
ofItem item: U, | |
toAnchor: (V) -> NSLayoutAnchor<T>, | |
ofOtherItem otherItem: V, | |
config: ConstraintConfig | |
) -> NSLayoutConstraint { | |
let fromAnchor = anchor(item) | |
let toAnchor = toAnchor(otherItem) | |
switch config.relation { | |
case .greaterThanOrEqual: | |
return fromAnchor.constraint(greaterThanOrEqualTo: toAnchor) |> config.config | |
case .lessThanOrEqual: | |
return fromAnchor.constraint(lessThanOrEqualTo: toAnchor) |> config.config | |
case .equal: | |
return fromAnchor.constraint(equalTo: toAnchor) |> config.config | |
} | |
} | |
static func pin<U>( | |
anchor: (U) -> NSLayoutDimension, | |
ofItem item: U, | |
config: ConstraintConfig | |
) -> NSLayoutConstraint { | |
let fromAnchor = anchor(item) | |
switch config.relation { | |
case .equal: | |
return fromAnchor.constraint(equalToConstant: 0) |> config.config | |
case .greaterThanOrEqual: | |
return fromAnchor.constraint(greaterThanOrEqualToConstant: 0) |> config.config | |
case .lessThanOrEqual: | |
return fromAnchor.constraint(lessThanOrEqualToConstant: 0) |> config.config | |
} | |
} | |
} | |
extension UIView { | |
func pin<U, T>(anchor: (UIView) -> NSLayoutAnchor<T>, toAnchor: (U) -> NSLayoutAnchor<T>, ofItem: U, config: ConstraintConfig = .defaultConfig) -> NSLayoutConstraint { | |
return AnchorMan.pin(anchor: anchor, ofItem: self, toAnchor: toAnchor, ofOtherItem: ofItem, config: config) | |
} | |
func pin<T>(anchor: (UIView) -> NSLayoutAnchor<T>, togetherWithView: UIView, config: ConstraintConfig = .defaultConfig) -> NSLayoutConstraint { | |
return self.pin(anchor: anchor, toAnchor: anchor, ofItem: togetherWithView, config: config) | |
} | |
func pinToView(view: UIView, edges: [EdgeToPin] = EdgeToPin.all) -> [NSLayoutConstraint] { | |
return edges.map({ | |
switch $0 { | |
case .top(let config): | |
return self.pin(anchor: Edge.top, togetherWithView: view, config: config) | |
case .leading(let config): | |
return self.pin(anchor: Edge.leading, togetherWithView: view, config: config) | |
case .trailing(let config): | |
return self.pin(anchor: Edge.trailing, togetherWithView: view, config: config) | |
case .bottom(let config): | |
return self.pin(anchor: Edge.bottom, togetherWithView: view, config: config) | |
} | |
}) | |
} | |
func pinToSuperView(edges: [EdgeToPin] = EdgeToPin.all) -> [NSLayoutConstraint] { | |
guard let superview = self.superview else { | |
fatalError("Sholud have superview") | |
} | |
return self.pinToView(view: superview, edges: edges) | |
} | |
func setSize(width: ConstraintConfig? = nil, height: ConstraintConfig? = nil) -> [NSLayoutConstraint] { | |
return [ | |
] | |
} | |
} | |
let vc = UIViewController() | |
let uiview = vc.view | |
let subview = UIView() | |
uiview?.addSubview(subview) | |
subview.pinToSuperView() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment