Clean up & Reshuffle some API

Moved some apis, added some equality operators and cleaned up some code.
This commit is contained in:
Robert Payne 2015-01-08 19:04:29 +13:00
parent 3642d9f568
commit 5a968ae864
6 changed files with 110 additions and 34 deletions

View File

@ -27,6 +27,38 @@ import UIKit
import AppKit import AppKit
#endif #endif
public protocol FloatConstantConstraint {
func update(float: Float)
}
public protocol DoubleConstantConstraint {
func update(float: Float)
}
public protocol CGFloatConstantConstraint {
func update(float: Float)
}
public protocol IntConstantConstraint {
func update(float: Float)
}
public protocol UIntConstantConstraint {
func update(float: Float)
}
public protocol CGPointConstantConstraint {
func update(float: Float)
}
public protocol CGSizeConstantConstraint {
func update(size: CGSize)
}
public protocol EdgeInsetsConstantConstraint {
func update(insets: EdgeInsets)
}
/** /**
* Constraint is a single item that defines all the properties for a single ConstraintMaker chain * Constraint is a single item that defines all the properties for a single ConstraintMaker chain
*/ */
@ -269,9 +301,14 @@ public class Constraint {
return self return self
} }
// MARK: install // MARK: internal
internal func install() -> Array<LayoutConstraint> {
if self.installedOnView != nil {
NSException(name: "Cannot Install Constraint", reason: "Already installed", userInfo: nil).raise()
return []
}
public func install() -> Array<LayoutConstraint> {
var installOnView: View? = nil var installOnView: View? = nil
if self.toItem.view != nil { if self.toItem.view != nil {
installOnView = Constraint.closestCommonSuperviewFromView(self.fromItem.view, toView: self.toItem.view) installOnView = Constraint.closestCommonSuperviewFromView(self.fromItem.view, toView: self.toItem.view)
@ -330,15 +367,13 @@ public class Constraint {
layoutConstraints.append(layoutConstraint) layoutConstraints.append(layoutConstraint)
} }
installOnView?.addConstraints(layoutConstraints) installOnView!.addConstraints(layoutConstraints)
self.installedOnView = installOnView self.installedOnView = installOnView
return layoutConstraints return layoutConstraints
} }
// MARK: uninstall internal func uninstall() {
public func uninstall() {
if let view = self.installedOnView { if let view = self.installedOnView {
#if os(iOS) #if os(iOS)
var installedConstraints = view.constraints() var installedConstraints = view.constraints()
@ -557,3 +592,11 @@ private extension NSLayoutAttribute {
return CGFloat(0); return CGFloat(0);
} }
} }
internal func ==(left: Constraint, right: Constraint) -> Bool {
return (left.fromItem == right.fromItem &&
left.toItem == right.toItem &&
left.relation == right.relation &&
left.multiplier == right.multiplier &&
left.priority == right.priority)
}

View File

@ -60,3 +60,20 @@ public class ConstraintItem {
} }
#endif #endif
} }
internal func ==(left: ConstraintItem, right: ConstraintItem) -> Bool {
if left.object == nil {
return false
}
if right.object == nil {
return false
}
if left.object !== right.object {
return false
}
if left.attributes != right.attributes {
return false
}
return true
}

View File

@ -70,11 +70,12 @@ public class ConstraintMaker {
let maker = ConstraintMaker(view: view) let maker = ConstraintMaker(view: view)
block(make: maker) block(make: maker)
var layoutConstraints = LayoutConstraint.layoutConstraintsInstalledOnView(view) var layoutConstraints = view.snp_installedLayoutConstraints
for constraint in maker.constraints { for constraint in maker.constraints {
layoutConstraints += constraint.install() layoutConstraints += constraint.install()
} }
LayoutConstraint.setLayoutConstraints(layoutConstraints, installedOnView: view)
view.snp_installedLayoutConstraints = layoutConstraints
} }
internal class func remakeConstraints(view: View, block: (make: ConstraintMaker) -> ()) { internal class func remakeConstraints(view: View, block: (make: ConstraintMaker) -> ()) {
@ -86,7 +87,7 @@ public class ConstraintMaker {
let maker = ConstraintMaker(view: view) let maker = ConstraintMaker(view: view)
block(make: maker) block(make: maker)
var layoutConstraints: Array<LayoutConstraint> = LayoutConstraint.layoutConstraintsInstalledOnView(view) var layoutConstraints: Array<LayoutConstraint> = view.snp_installedLayoutConstraints
for existingLayoutConstraint in layoutConstraints { for existingLayoutConstraint in layoutConstraints {
existingLayoutConstraint.constraint?.uninstall() existingLayoutConstraint.constraint?.uninstall()
} }
@ -95,13 +96,15 @@ public class ConstraintMaker {
for constraint in maker.constraints { for constraint in maker.constraints {
layoutConstraints += constraint.install() layoutConstraints += constraint.install()
} }
LayoutConstraint.setLayoutConstraints(layoutConstraints, installedOnView: view)
view.snp_installedLayoutConstraints = layoutConstraints
} }
internal class func removeConstraints(view: View) { internal class func removeConstraints(view: View) {
for existingLayoutConstraint in LayoutConstraint.layoutConstraintsInstalledOnView(view) { for existingLayoutConstraint in view.snp_installedLayoutConstraints {
existingLayoutConstraint.constraint?.uninstall() existingLayoutConstraint.constraint?.uninstall()
} }
LayoutConstraint.setLayoutConstraints([], installedOnView: view)
view.snp_installedLayoutConstraints = []
} }
} }

View File

@ -31,21 +31,5 @@ import AppKit
* LayoutConstraint is a subclass of NSLayoutConstraint to assist Snappy and also provide better debugging * LayoutConstraint is a subclass of NSLayoutConstraint to assist Snappy and also provide better debugging
*/ */
public class LayoutConstraint: NSLayoutConstraint { public class LayoutConstraint: NSLayoutConstraint {
// internal
internal var constraint: Constraint? internal var constraint: Constraint?
internal class func layoutConstraintsInstalledOnView(view: View) -> Array<LayoutConstraint> {
var constraints = objc_getAssociatedObject(view, &layoutConstraintsInstalledOnViewKey) as? Array<LayoutConstraint>
if constraints != nil {
return constraints!
} }
return []
}
internal class func setLayoutConstraints(layoutConstraints: Array<LayoutConstraint>, installedOnView view: View) {
objc_setAssociatedObject(view, &layoutConstraintsInstalledOnViewKey, layoutConstraints, UInt(OBJC_ASSOCIATION_RETAIN_NONATOMIC))
}
}
private var layoutConstraintsInstalledOnViewKey = ""

View File

@ -30,6 +30,9 @@ public typealias View = NSView
#endif #endif
public extension View { public extension View {
// normal
public var snp_left: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.Left) } public var snp_left: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.Left) }
public var snp_top: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.Top) } public var snp_top: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.Top) }
public var snp_right: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.Right) } public var snp_right: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.Right) }
@ -42,8 +45,8 @@ public extension View {
public var snp_centerY: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.CenterY) } public var snp_centerY: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.CenterY) }
public var snp_baseline: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.Baseline) } public var snp_baseline: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.Baseline) }
#if os(iOS)
public var snp_firstBaseline: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.FirstBaseline) } public var snp_firstBaseline: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.FirstBaseline) }
public var snp_leftMargin: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.LeftMargin) } public var snp_leftMargin: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.LeftMargin) }
public var snp_rightMargin: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.RightMargin) } public var snp_rightMargin: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.RightMargin) }
public var snp_topMargin: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.TopMargin) } public var snp_topMargin: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.TopMargin) }
@ -52,18 +55,27 @@ public extension View {
public var snp_trailingMargin: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.TrailingMargin) } public var snp_trailingMargin: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.TrailingMargin) }
public var snp_centerXWithinMargin: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.CenterXWithinMargins) } public var snp_centerXWithinMargin: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.CenterXWithinMargins) }
public var snp_centerYWithinMargin: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.CenterYWithinMargins) } public var snp_centerYWithinMargin: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.CenterYWithinMargins) }
#endif
// aggregates
public var snp_edges: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.Edges) } public var snp_edges: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.Edges) }
public var snp_size: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.Size) } public var snp_size: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.Size) }
public var snp_center: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.Center) } public var snp_center: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.Center) }
#if os(iOS)
public var snp_margins: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.Margins) } public var snp_margins: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.Margins) }
public var snp_centerWithinMargins: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.CenterWithinMargins) } public var snp_centerWithinMargins: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.CenterWithinMargins) }
#endif
public func snp_makeConstraints(block: (maker: ConstraintMaker) -> ()) { public func snp_makeConstraints(block: (maker: ConstraintMaker) -> ()) {
ConstraintMaker.makeConstraints(self, block: block) ConstraintMaker.makeConstraints(self, block: block)
} }
public func snp_updateConstraints(block: (maker: ConstraintMaker) -> ()) {
ConstraintMaker.updateConstraints(self, block: block)
}
public func snp_remakeConstraints(block: (maker: ConstraintMaker) -> ()) { public func snp_remakeConstraints(block: (maker: ConstraintMaker) -> ()) {
ConstraintMaker.remakeConstraints(self, block: block) ConstraintMaker.remakeConstraints(self, block: block)
} }
@ -71,4 +83,21 @@ public extension View {
public func snp_removeConstraints() { public func snp_removeConstraints() {
ConstraintMaker.removeConstraints(self) ConstraintMaker.removeConstraints(self)
} }
// internal
internal var snp_installedLayoutConstraints: Array<LayoutConstraint> {
get {
var constraints = objc_getAssociatedObject(self, &installedLayoutConstraintsKey) as? Array<LayoutConstraint>
if constraints != nil {
return constraints!
} }
return []
}
set {
objc_setAssociatedObject(self, &installedLayoutConstraintsKey, newValue, UInt(OBJC_ASSOCIATION_RETAIN_NONATOMIC))
}
}
}
private var installedLayoutConstraintsKey = ""