Răsfoiți Sursa

API updates, migrate away from iOS 7.0 support

Robert Payne 9 ani în urmă
părinte
comite
9d0232ca08

+ 5 - 2
SnapKit.xcodeproj/project.pbxproj

@@ -507,6 +507,7 @@
 					EEBCC9E119CC627D0083B827 = {
 						CreatedOnToolsVersion = 6.0;
 						LastSwiftMigration = 0800;
+						ProvisioningStyle = Automatic;
 					};
 					EECDB3791AC0C9D4006BBC11 = {
 						CreatedOnToolsVersion = 6.2;
@@ -945,7 +946,8 @@
 		EEBCC9EC19CC627E0083B827 /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				FRAMEWORK_SEARCH_PATHS = "$(inherited)";
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+				DEVELOPMENT_TEAM = "";
 				INFOPLIST_FILE = "$(SRCROOT)/Tests/Info.plist";
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 				PRODUCT_BUNDLE_IDENTIFIER = "io.snapkit.$(PRODUCT_NAME:rfc1034identifier)";
@@ -957,7 +959,8 @@
 		EEBCC9ED19CC627E0083B827 /* Release */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				FRAMEWORK_SEARCH_PATHS = "$(inherited)";
+				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+				DEVELOPMENT_TEAM = "";
 				INFOPLIST_FILE = "$(SRCROOT)/Tests/Info.plist";
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 				PRODUCT_BUNDLE_IDENTIFIER = "io.snapkit.$(PRODUCT_NAME:rfc1034identifier)";

+ 76 - 228
Source/Constraint.swift

@@ -27,10 +27,10 @@
     import AppKit
 #endif
 
-
 public class Constraint {
     
     internal let sourceLocation: (String, UInt)
+    internal let label: String?
     
     private let from: ConstraintItem
     private let to: ConstraintItem
@@ -46,7 +46,7 @@ public class Constraint {
           self.updateConstantAndPriorityIfNeeded()
         }
     }
-    private var installInfo: ConstraintInstallInfo? = nil
+    private let layoutConstraints: NSHashTable<LayoutConstraint>
     
     // MARK: Initialization
     
@@ -54,6 +54,7 @@ public class Constraint {
                   to: ConstraintItem,
                   relation: ConstraintRelation,
                   sourceLocation: (String, UInt),
+                  label: String?,
                   multiplier: ConstraintMultiplierTarget,
                   constant: ConstraintConstantTarget,
                   priority: ConstraintPriorityTarget) {
@@ -61,27 +62,67 @@ public class Constraint {
         self.to = to
         self.relation = relation
         self.sourceLocation = sourceLocation
+        self.label = label
         self.multiplier = multiplier
         self.constant = constant
         self.priority = priority
+        self.layoutConstraints = NSHashTable<LayoutConstraint>.weakObjects()
+        
+        // get attributes
+        let layoutFromAttributes = self.from.attributes.layoutAttributes
+        let layoutToAttributes = self.to.attributes.layoutAttributes
+        
+        // get layout from
+        let layoutFrom: ConstraintView = self.from.view!
+        
+        // get relation
+        let layoutRelation = self.relation.layoutRelation
+        
+        for layoutFromAttribute in layoutFromAttributes {
+            // get layout to attribute
+            let layoutToAttribute = (layoutToAttributes.count > 0) ? layoutToAttributes[0] : layoutFromAttribute
+            
+            // get layout constant
+            let layoutConstant: CGFloat = self.constant.constraintConstantTargetValueFor(layoutAttribute: layoutToAttribute)
+            
+            // get layout to
+            #if os(iOS) || os(tvOS)
+                let layoutTo: AnyObject? = self.to.view ?? self.to.layoutSupport
+            #else
+                let layoutTo: AnyObject? = self.to.view
+            #endif
+            
+            // create layout constraint
+            let layoutConstraint = LayoutConstraint(
+                item: layoutFrom,
+                attribute: layoutFromAttribute,
+                relatedBy: layoutRelation,
+                toItem: layoutTo,
+                attribute: layoutToAttribute,
+                multiplier: self.multiplier.constraintMultiplierTargetValue,
+                constant: layoutConstant
+            )
+            
+            // set label
+            layoutConstraint.label = self.label
+            
+            // set priority
+            layoutConstraint.priority = self.priority.constraintPriorityTargetValue
+            
+            // set constraint
+            layoutConstraint.constraint = self
+            
+            // append
+            self.layoutConstraints.add(layoutConstraint)
+        }
     }
     
     // MARK: Public
     
-    public func install() -> [NSLayoutConstraint] {
-        return self.installIfNeeded(updateExisting: false)
-    }
-    
-    public func uninstall() {
-        self.uninstallIfNeeded()
-    }
-    
-    @available(iOS 8.0, OSX 10.10, *)
     public func activate() {
         self.activateIfNeeded()
     }
     
-    @available(iOS 8.0, OSX 10.10, *)
     public func deactivate() {
         self.deactivateIfNeeded()
     }
@@ -128,248 +169,55 @@ public class Constraint {
     // MARK: Internal
     
     internal func updateConstantAndPriorityIfNeeded() {
-        guard let installInfo = self.installInfo else {
-            return
-        }
-        for layoutConstraint in installInfo.layoutConstraints.allObjects as! [LayoutConstraint] {
+        for layoutConstraint in self.layoutConstraints.allObjects {
             let attribute = (layoutConstraint.secondAttribute == .notAnAttribute) ? layoutConstraint.firstAttribute : layoutConstraint.secondAttribute
             layoutConstraint.constant = self.constant.constraintConstantTargetValueFor(layoutAttribute: attribute)
             layoutConstraint.priority = self.priority.constraintPriorityTargetValue
         }
     }
     
-    internal func installIfNeeded(updateExisting: Bool = false) -> [NSLayoutConstraint] {
-        let installOnView: ConstraintView?
-        
-        if let view = self.to.view {
-            guard let closestSuperview = closestCommonSuperviewFromView(self.from.view, toView: view) else {
-                fatalError("Cannot Install Constraint. No common superview. (\(self.sourceLocation.0), \(self.sourceLocation.1))")
-            }
-            installOnView = closestSuperview
-        } else if self.from.attributes.isSubset(of: ConstraintAttributes.Width + ConstraintAttributes.Height) {
-            installOnView = self.from.view
-        } else {
-            guard let superview = self.from.view?.superview else {
-                fatalError("Cannot Install Constraint. No superview. (\(self.sourceLocation.0), \(self.sourceLocation.1))")
-            }
-            installOnView = superview
-        }
-        
-        guard self.installInfo?.view == nil ||
-              self.installInfo?.view == installOnView else {
-            fatalError("Cannot Install Constraint. Already installed on different view. (\(self.sourceLocation.0), \(self.sourceLocation.1))")
-        }
-        
-        // setup array to store new layout constraints
-        var newLayoutConstraints = [LayoutConstraint]()
-        
-        // get attributes
-        let layoutFromAttributes = self.from.attributes.layoutAttributes
-        let layoutToAttributes = self.to.attributes.layoutAttributes
-        
-        // get layout from
-        let layoutFrom: ConstraintView = self.from.view!
-        
-        // get relation
-        let layoutRelation = self.relation.layoutRelation
-        
-        for layoutFromAttribute in layoutFromAttributes {
-            // get layout to attribute
-            let layoutToAttribute = (layoutToAttributes.count > 0) ? layoutToAttributes[0] : layoutFromAttribute
-            
-            // get layout constant
-            let layoutConstant: CGFloat = self.constant.constraintConstantTargetValueFor(layoutAttribute: layoutToAttribute)
-            
-            // get layout to
-            #if os(iOS) || os(tvOS)
-                var layoutTo: AnyObject? = self.to.view ?? self.to.layoutSupport
-            #else
-                var layoutTo: AnyObject? = self.to.view
-            #endif
-            if layoutTo == nil && layoutToAttribute != .width && layoutToAttribute != .height {
-                layoutTo = installOnView
-            }
-            
-            // create layout constraint
-            let layoutConstraint = LayoutConstraint(
-                item: layoutFrom,
-                attribute: layoutFromAttribute,
-                relatedBy: layoutRelation,
-                toItem: layoutTo,
-                attribute: layoutToAttribute,
-                multiplier: self.multiplier.constraintMultiplierTargetValue,
-                constant: layoutConstant
-            )
-            
-            // set priority
-            layoutConstraint.priority = self.priority.constraintPriorityTargetValue
-            
-            // set constraint
-            layoutConstraint.constraint = self
-            
-            // append
-            newLayoutConstraints.append(layoutConstraint)
-        }
+    internal func activateIfNeeded(updatingExisting: Bool = false) {
+        let view = self.from.view!
+        let layoutConstraints = self.layoutConstraints.allObjects
+        let existingLayoutConstraints = view.snp.layoutConstraints
         
-        // updating logic
-        if updateExisting {
-            
-            // get existing constraints for this view
-            let existingLayoutConstraints = layoutFrom.snp.installedLayoutConstraints.reversed()
+        if updatingExisting && existingLayoutConstraints.count > 0 {
             
-            // array that will contain only new layout constraints to keep
-            var newLayoutConstraintsToKeep = [LayoutConstraint]()
-            
-            // begin looping
-            for layoutConstraint in newLayoutConstraints {
-                // layout constraint that should be updated
-                var updateLayoutConstraint: LayoutConstraint? = nil
-                
-                // loop through existing and check for match
-                for existingLayoutConstraint in existingLayoutConstraints {
-                    if existingLayoutConstraint == layoutConstraint {
-                        updateLayoutConstraint = existingLayoutConstraint
-                        break
-                    }
+            for layoutConstraint in layoutConstraints {
+                let existingLayoutConstraint = existingLayoutConstraints.first { $0 == layoutConstraint }
+                guard let updateLayoutConstraint = existingLayoutConstraint else {
+                    fatalError("Updated constraint could not find existing matching constraint to update: \(layoutConstraint)")
                 }
                 
-                // if we have existing one lets just update the constant
-                if updateLayoutConstraint != nil {
-                    updateLayoutConstraint!.constant = layoutConstraint.constant
-                }
-                // otherwise add this layout constraint to new keep list
-                else {
-                    newLayoutConstraintsToKeep.append(layoutConstraint)
-                }
+                let updateLayoutAttribute = (updateLayoutConstraint.secondAttribute == .notAnAttribute) ? updateLayoutConstraint.firstAttribute : updateLayoutConstraint.secondAttribute
+                updateLayoutConstraint.constant = self.constant.constraintConstantTargetValueFor(layoutAttribute: updateLayoutAttribute)
             }
             
-            // set constraints to only new ones
-            newLayoutConstraints = newLayoutConstraintsToKeep
-        }
-        
-        // add constraints
-        #if SNAPKIT_DEPLOYMENT_LEGACY && (os(iOS) || os(tvOS))
-            if #available(iOS 8.0, *) {
-                NSLayoutConstraint.activate(newLayoutConstraints)
-            } else {
-                installOnView?.addConstraints(newLayoutConstraints)
-            }
-        #else
-            NSLayoutConstraint.activate(newLayoutConstraints)
-        #endif
-        
-        // set install info
-        self.installInfo = ConstraintInstallInfo(view: installOnView, layoutConstraints: NSHashTable.weakObjects())
-        
-        // store which layout constraints are installed for this constraint
-        for layoutConstraint in newLayoutConstraints {
-            self.installInfo!.layoutConstraints.add(layoutConstraint)
-        }
-        
-        // store the layout constraints against the layout from view
-        layoutFrom.snp.appendInstalledLayoutConstraints(newLayoutConstraints)
-        
-        return newLayoutConstraints
-    }
-    
-    internal func uninstallIfNeeded() {
-        defer {
-            self.installInfo = nil
-        }
-        
-        guard let installedLayoutConstraints = self.installInfo?.layoutConstraints.allObjects as? [LayoutConstraint],
-              installedLayoutConstraints.count > 0 else {
-            return
-        }
-        
-        #if SNAPKIT_DEPLOYMENT_LEGACY && !os(OSX)
-            if #available(iOS 8.0, *) {
-                NSLayoutConstraint.deactivate(installedLayoutConstraints)
-            } else if let installedOnView = installInfo?.view {
-                installedOnView.removeConstraints(installedLayoutConstraints)
-            }
-        #else
-            NSLayoutConstraint.deactivate(installedLayoutConstraints)
-        #endif
-        
-        // remove the constraints from the from item view
-        self.from.view?.snp.removeInstalledLayoutConstraints(installedLayoutConstraints)
-    }
-    
-    internal func activateIfNeeded() {
-        guard self.installInfo != nil else {
-            _ = self.installIfNeeded()
-            return
-        }
-        #if SNAPKIT_DEPLOYMENT_LEGACY
-            guard #available(iOS 8.0, OSX 10.10, *) else {
-                _ = self.installIfNeeded()
-                return
-            }
-        #endif
-        
-        guard let layoutConstraints = self.installInfo?.layoutConstraints.allObjects as? [LayoutConstraint],
-              layoutConstraints.count > 0 else {
-                return
+        } else {
+            NSLayoutConstraint.activate(layoutConstraints)
+            view.snp.add(layoutConstraints: layoutConstraints)
         }
         
-        NSLayoutConstraint.activate(layoutConstraints)
+        print(view, layoutConstraints.count, existingLayoutConstraints.count)
     }
     
     internal func deactivateIfNeeded() {
-        #if SNAPKIT_DEPLOYMENT_LEGACY
-            guard #available(iOS 8.0, OSX 10.10, *) else {
-                return
-            }
-        #endif
-        
-        guard let layoutConstraints = self.installInfo?.layoutConstraints.allObjects as? [LayoutConstraint],
-              layoutConstraints.count > 0 else {
-            return
-        }
-        
+        let view = self.from.view!
+        let layoutConstraints = self.layoutConstraints.allObjects
         NSLayoutConstraint.deactivate(layoutConstraints)
+        view.snp.remove(layoutConstraints: layoutConstraints)
     }
-    
 }
 
-private final class ConstraintInstallInfo {
+extension Constraint: Hashable {
     
-    private weak var view: ConstraintView? = nil
-    private let layoutConstraints: NSHashTable<AnyObject>
-    
-    private init(view: ConstraintView?, layoutConstraints: NSHashTable<AnyObject>) {
-        self.view = view
-        self.layoutConstraints = layoutConstraints
+    public var hashValue: Int {
+        return self.layoutConstraints.hashValue
     }
     
 }
 
-private func closestCommonSuperviewFromView(_ fromView: ConstraintView?, toView: ConstraintView?) -> ConstraintView? {
-    var views = Set<ConstraintView>()
-    var fromView = fromView
-    var toView = toView
-    repeat {
-        if let view = toView {
-            if views.contains(view) {
-                return view
-            }
-            views.insert(view)
-            toView = view.superview
-        }
-        if let view = fromView {
-            if views.contains(view) {
-                return view
-            }
-            views.insert(view)
-            fromView = view.superview
-        }
-    } while (fromView != nil || toView != nil)
-    
-    return nil
-}
-
-private func ==(lhs: Constraint, rhs: Constraint) -> Bool {
+public func ==(lhs: Constraint, rhs: Constraint) -> Bool {
     return (lhs.from == rhs.from &&
             lhs.to == rhs.to &&
             lhs.relation == rhs.relation &&

+ 55 - 52
Source/ConstraintAttributes.swift

@@ -51,117 +51,120 @@ internal struct ConstraintAttributes: OptionSet {
     
     // normal
     
-    internal static var None: ConstraintAttributes { return self.init(0) }
-    internal static var Left: ConstraintAttributes { return self.init(1) }
-    internal static var Top: ConstraintAttributes {  return self.init(2) }
-    internal static var Right: ConstraintAttributes { return self.init(4) }
-    internal static var Bottom: ConstraintAttributes { return self.init(8) }
-    internal static var Leading: ConstraintAttributes { return self.init(16) }
-    internal static var Trailing: ConstraintAttributes { return self.init(32) }
-    internal static var Width: ConstraintAttributes { return self.init(64) }
-    internal static var Height: ConstraintAttributes { return self.init(128) }
-    internal static var CenterX: ConstraintAttributes { return self.init(256) }
-    internal static var CenterY: ConstraintAttributes { return self.init(512) }
-    internal static var Baseline: ConstraintAttributes { return self.init(1024) }
+    internal static var none: ConstraintAttributes { return self.init(0) }
+    internal static var left: ConstraintAttributes { return self.init(1) }
+    internal static var top: ConstraintAttributes {  return self.init(2) }
+    internal static var right: ConstraintAttributes { return self.init(4) }
+    internal static var bottom: ConstraintAttributes { return self.init(8) }
+    internal static var leading: ConstraintAttributes { return self.init(16) }
+    internal static var trailing: ConstraintAttributes { return self.init(32) }
+    internal static var width: ConstraintAttributes { return self.init(64) }
+    internal static var height: ConstraintAttributes { return self.init(128) }
+    internal static var centerX: ConstraintAttributes { return self.init(256) }
+    internal static var centerY: ConstraintAttributes { return self.init(512) }
+    internal static var lastBaseline: ConstraintAttributes { return self.init(1024) }
+    
+    @available(iOS 8.0, OSX 10.11, *)
+    internal static var firstBaseline: ConstraintAttributes { return self.init(2048) }
     
     @available(iOS 8.0, *)
-    internal static var FirstBaseline: ConstraintAttributes { return self.init(2048) }
-    @available(iOS 8.0, *)
-    internal static var LeftMargin: ConstraintAttributes { return self.init(4096) }
+    internal static var leftMargin: ConstraintAttributes { return self.init(4096) }
+    
     @available(iOS 8.0, *)
-    internal static var RightMargin: ConstraintAttributes { return self.init(8192) }
+    internal static var rightMargin: ConstraintAttributes { return self.init(8192) }
+    
     @available(iOS 8.0, *)
-    internal static var TopMargin: ConstraintAttributes { return self.init(16384) }
+    internal static var topMargin: ConstraintAttributes { return self.init(16384) }
+    
     @available(iOS 8.0, *)
-    internal static var BottomMargin: ConstraintAttributes { return self.init(32768) }
+    internal static var bottomMargin: ConstraintAttributes { return self.init(32768) }
+    
     @available(iOS 8.0, *)
-    internal static var LeadingMargin: ConstraintAttributes { return self.init(65536) }
+    internal static var leadingMargin: ConstraintAttributes { return self.init(65536) }
+    
     @available(iOS 8.0, *)
-    internal static var TrailingMargin: ConstraintAttributes { return self.init(131072) }
+    internal static var trailingMargin: ConstraintAttributes { return self.init(131072) }
+    
     @available(iOS 8.0, *)
-    internal static var CenterXWithinMargins: ConstraintAttributes { return self.init(262144) }
+    internal static var centerXWithinMargins: ConstraintAttributes { return self.init(262144) }
+    
     @available(iOS 8.0, *)
-    internal static var CenterYWithinMargins: ConstraintAttributes { return self.init(524288) }
+    internal static var centerYWithinMargins: ConstraintAttributes { return self.init(524288) }
     
     // aggregates
     
-    internal static var Edges: ConstraintAttributes { return self.init(15) }
-    internal static var Size: ConstraintAttributes { return self.init(192) }
-    internal static var Center: ConstraintAttributes { return self.init(768) }
+    internal static var edges: ConstraintAttributes { return self.init(15) }
+    internal static var size: ConstraintAttributes { return self.init(192) }
+    internal static var center: ConstraintAttributes { return self.init(768) }
     
     @available(iOS 8.0, *)
-    internal static var Margins: ConstraintAttributes { return self.init(61440) }
+    internal static var margins: ConstraintAttributes { return self.init(61440) }
     
     @available(iOS 8.0, *)
-    internal static var CenterWithinMargins: ConstraintAttributes { return self.init(786432) }
+    internal static var centerWithinMargins: ConstraintAttributes { return self.init(786432) }
     
     internal var layoutAttributes:[NSLayoutAttribute] {
         var attrs = [NSLayoutAttribute]()
-        if (self.contains(ConstraintAttributes.Left)) {
+        if (self.contains(ConstraintAttributes.left)) {
             attrs.append(.left)
         }
-        if (self.contains(ConstraintAttributes.Top)) {
+        if (self.contains(ConstraintAttributes.top)) {
             attrs.append(.top)
         }
-        if (self.contains(ConstraintAttributes.Right)) {
+        if (self.contains(ConstraintAttributes.right)) {
             attrs.append(.right)
         }
-        if (self.contains(ConstraintAttributes.Bottom)) {
+        if (self.contains(ConstraintAttributes.bottom)) {
             attrs.append(.bottom)
         }
-        if (self.contains(ConstraintAttributes.Leading)) {
+        if (self.contains(ConstraintAttributes.leading)) {
             attrs.append(.leading)
         }
-        if (self.contains(ConstraintAttributes.Trailing)) {
+        if (self.contains(ConstraintAttributes.trailing)) {
             attrs.append(.trailing)
         }
-        if (self.contains(ConstraintAttributes.Width)) {
+        if (self.contains(ConstraintAttributes.width)) {
             attrs.append(.width)
         }
-        if (self.contains(ConstraintAttributes.Height)) {
+        if (self.contains(ConstraintAttributes.height)) {
             attrs.append(.height)
         }
-        if (self.contains(ConstraintAttributes.CenterX)) {
+        if (self.contains(ConstraintAttributes.centerX)) {
             attrs.append(.centerX)
         }
-        if (self.contains(ConstraintAttributes.CenterY)) {
+        if (self.contains(ConstraintAttributes.centerY)) {
             attrs.append(.centerY)
         }
-        if (self.contains(ConstraintAttributes.Baseline)) {
+        if (self.contains(ConstraintAttributes.lastBaseline)) {
             attrs.append(.lastBaseline)
         }
         
         #if os(iOS) || os(tvOS)
-            #if SNAPKIT_DEPLOYMENT_LEGACY
-                guard #available(iOS 8.0, *) else {
-                    return attrs
-                }
-            #endif
-            if (self.contains(ConstraintAttributes.FirstBaseline)) {
+            if (self.contains(ConstraintAttributes.firstBaseline)) {
                 attrs.append(.firstBaseline)
             }
-            if (self.contains(ConstraintAttributes.LeftMargin)) {
+            if (self.contains(ConstraintAttributes.leftMargin)) {
                 attrs.append(.leftMargin)
             }
-            if (self.contains(ConstraintAttributes.RightMargin)) {
+            if (self.contains(ConstraintAttributes.rightMargin)) {
                 attrs.append(.rightMargin)
             }
-            if (self.contains(ConstraintAttributes.TopMargin)) {
+            if (self.contains(ConstraintAttributes.topMargin)) {
                 attrs.append(.topMargin)
             }
-            if (self.contains(ConstraintAttributes.BottomMargin)) {
+            if (self.contains(ConstraintAttributes.bottomMargin)) {
                 attrs.append(.bottomMargin)
             }
-            if (self.contains(ConstraintAttributes.LeadingMargin)) {
+            if (self.contains(ConstraintAttributes.leadingMargin)) {
                 attrs.append(.leadingMargin)
             }
-            if (self.contains(ConstraintAttributes.TrailingMargin)) {
+            if (self.contains(ConstraintAttributes.trailingMargin)) {
                 attrs.append(.trailingMargin)
             }
-            if (self.contains(ConstraintAttributes.CenterXWithinMargins)) {
+            if (self.contains(ConstraintAttributes.centerXWithinMargins)) {
                 attrs.append(.centerXWithinMargins)
             }
-            if (self.contains(ConstraintAttributes.CenterYWithinMargins)) {
+            if (self.contains(ConstraintAttributes.centerYWithinMargins)) {
                 attrs.append(.centerYWithinMargins)
             }
         #endif

+ 2 - 0
Source/ConstraintDescription.swift

@@ -34,6 +34,7 @@ public class ConstraintDescription {
     internal var attributes: ConstraintAttributes
     internal var relation: ConstraintRelation? = nil
     internal var sourceLocation: (String, UInt)? = nil
+    internal var label: String? = nil
     internal var related: ConstraintItem? = nil
     internal var multiplier: ConstraintMultiplierTarget = 1.0
     internal var constant: ConstraintConstantTarget = 0.0
@@ -51,6 +52,7 @@ public class ConstraintDescription {
             to: related,
             relation: relation,
             sourceLocation: sourceLocation,
+            label: self.label,
             multiplier: self.multiplier,
             constant: self.constant,
             priority: self.priority

+ 43 - 28
Source/ConstraintMaker.swift

@@ -30,95 +30,109 @@
 public class ConstraintMaker {
     
     public var left: ConstraintMakerExtendable {
-        return self.makeExtendableWithAttributes(ConstraintAttributes.Left)
+        return self.makeExtendableWithAttributes(.left)
     }
+    
     public var top: ConstraintMakerExtendable {
-        return self.makeExtendableWithAttributes(ConstraintAttributes.Top)
+        return self.makeExtendableWithAttributes(.top)
     }
+    
     public var bottom: ConstraintMakerExtendable {
-        return self.makeExtendableWithAttributes(ConstraintAttributes.Bottom)
+        return self.makeExtendableWithAttributes(.bottom)
     }
+    
     public var right: ConstraintMakerExtendable {
-        return self.makeExtendableWithAttributes(ConstraintAttributes.Right)
+        return self.makeExtendableWithAttributes(.right)
     }
+    
     public var leading: ConstraintMakerExtendable {
-        return self.makeExtendableWithAttributes(ConstraintAttributes.Leading)
+        return self.makeExtendableWithAttributes(.leading)
     }
+    
     public var trailing: ConstraintMakerExtendable {
-        return self.makeExtendableWithAttributes(ConstraintAttributes.Trailing)
+        return self.makeExtendableWithAttributes(.trailing)
     }
+    
     public var width: ConstraintMakerExtendable {
-        return self.makeExtendableWithAttributes(ConstraintAttributes.Width)
+        return self.makeExtendableWithAttributes(.width)
     }
+    
     public var height: ConstraintMakerExtendable {
-        return self.makeExtendableWithAttributes(ConstraintAttributes.Height)
+        return self.makeExtendableWithAttributes(.height)
     }
     
     public var centerX: ConstraintMakerExtendable {
-        return self.makeExtendableWithAttributes(ConstraintAttributes.CenterX)
+        return self.makeExtendableWithAttributes(.centerX)
     }
+    
     public var centerY: ConstraintMakerExtendable {
-        return self.makeExtendableWithAttributes(ConstraintAttributes.CenterY)
+        return self.makeExtendableWithAttributes(.centerY)
     }
+    
+    @available(*, deprecated:0.40.0, message:"Use lastBaseline instead")
     public var baseline: ConstraintMakerExtendable {
-        return self.makeExtendableWithAttributes(ConstraintAttributes.Baseline)
+        return self.makeExtendableWithAttributes(.lastBaseline)
     }
     
-    @available(iOS 8.0, *)
+    public var lastBaseline: ConstraintMakerExtendable {
+        return self.makeExtendableWithAttributes(.lastBaseline)
+    }
+    
+    @available(iOS 8.0, OSX 10.11, *)
     public var firstBaseline: ConstraintMakerExtendable {
-        return self.makeExtendableWithAttributes(ConstraintAttributes.FirstBaseline)
+        return self.makeExtendableWithAttributes(.firstBaseline)
     }
     
     @available(iOS 8.0, *)
     public var leftMargin: ConstraintMakerExtendable {
-        return self.makeExtendableWithAttributes(ConstraintAttributes.LeftMargin)
+        return self.makeExtendableWithAttributes(.leftMargin)
     }
     
     @available(iOS 8.0, *)
     public var rightMargin: ConstraintMakerExtendable {
-        return self.makeExtendableWithAttributes(ConstraintAttributes.RightMargin)
+        return self.makeExtendableWithAttributes(.rightMargin)
     }
     
     @available(iOS 8.0, *)
     public var bottomMargin: ConstraintMakerExtendable {
-        return self.makeExtendableWithAttributes(ConstraintAttributes.BottomMargin)
+        return self.makeExtendableWithAttributes(.bottomMargin)
     }
     
     @available(iOS 8.0, *)
     public var leadingMargin: ConstraintMakerExtendable {
-        return self.makeExtendableWithAttributes(ConstraintAttributes.LeadingMargin)
+        return self.makeExtendableWithAttributes(.leadingMargin)
     }
     
     @available(iOS 8.0, *)
     public var trailingMargin: ConstraintMakerExtendable {
-        return self.makeExtendableWithAttributes(ConstraintAttributes.TrailingMargin)
+        return self.makeExtendableWithAttributes(.trailingMargin)
     }
     
     @available(iOS 8.0, *)
     public var centerXWithinMargins: ConstraintMakerExtendable {
-        return self.makeExtendableWithAttributes(ConstraintAttributes.CenterXWithinMargins)
+        return self.makeExtendableWithAttributes(.centerXWithinMargins)
     }
     
     @available(iOS 8.0, *)
     public var centerYWithinMargins: ConstraintMakerExtendable {
-        return self.makeExtendableWithAttributes(ConstraintAttributes.CenterYWithinMargins)
+        return self.makeExtendableWithAttributes(.centerYWithinMargins)
     }
     
     public var edges: ConstraintMakerExtendable {
-        return self.makeExtendableWithAttributes(ConstraintAttributes.Edges)
+        return self.makeExtendableWithAttributes(.edges)
     }
     public var size: ConstraintMakerExtendable {
-        return self.makeExtendableWithAttributes(ConstraintAttributes.Size)
+        return self.makeExtendableWithAttributes(.size)
     }
     
     @available(iOS 8.0, *)
     public var margins: ConstraintMakerExtendable {
-        return self.makeExtendableWithAttributes(ConstraintAttributes.Margins)
+        return self.makeExtendableWithAttributes(.margins)
     }
     
     @available(iOS 8.0, *)
     public var centerWithinMargins: ConstraintMakerExtendable {
-        return self.makeExtendableWithAttributes(ConstraintAttributes.CenterWithinMargins)
+        return self.makeExtendableWithAttributes(.centerWithinMargins)
     }
     
     private let view: ConstraintView
@@ -153,7 +167,7 @@ public class ConstraintMaker {
             .filter { $0 != nil }
             .map { $0! }
         for constraint in constraints {
-            let _ = constraint.installIfNeeded()
+            constraint.activateIfNeeded(updatingExisting: false)
         }
     }
     
@@ -170,13 +184,14 @@ public class ConstraintMaker {
             .filter { $0 != nil }
             .map { $0! }
         for constraint in constraints {
-            let _ = constraint.installIfNeeded(updateExisting: true)
+            constraint.activateIfNeeded(updatingExisting: true)
         }
     }
     
     internal static func removeConstraints(view: ConstraintView) {
-        for layoutConstraint in view.snp.installedLayoutConstraints {
-            layoutConstraint.constraint?.uninstall()
+        let constraints = view.snp.layoutConstraints.map { $0.constraint! }
+        for constraint in constraints {
+            constraint.deactivateIfNeeded()
         }
     }
     

+ 30 - 24
Source/ConstraintMakerExtendable.swift

@@ -31,126 +31,132 @@
 public class ConstraintMakerExtendable: ConstraintMakerRelatable {
     
     public var left: ConstraintMakerExtendable {
-        self.description.attributes += ConstraintAttributes.Left
+        self.description.attributes += .left
         return self
     }
     
     public var top: ConstraintMakerExtendable {
-        self.description.attributes += ConstraintAttributes.Top
+        self.description.attributes += .top
         return self
     }
     
     public var bottom: ConstraintMakerExtendable {
-        self.description.attributes += ConstraintAttributes.Bottom
+        self.description.attributes += .bottom
         return self
     }
     
     public var right: ConstraintMakerExtendable {
-        self.description.attributes += ConstraintAttributes.Right
+        self.description.attributes += .right
         return self
     }
     
     public var leading: ConstraintMakerExtendable {
-        self.description.attributes += ConstraintAttributes.Leading
+        self.description.attributes += .leading
         return self
     }
     
     public var trailing: ConstraintMakerExtendable {
-        self.description.attributes += ConstraintAttributes.Trailing
+        self.description.attributes += .trailing
         return self
     }
     
     public var width: ConstraintMakerExtendable {
-        self.description.attributes += ConstraintAttributes.Width
+        self.description.attributes += .width
         return self
     }
     
     public var height: ConstraintMakerExtendable {
-        self.description.attributes += ConstraintAttributes.Height
+        self.description.attributes += .height
         return self
     }
     
     public var centerX: ConstraintMakerExtendable {
-        self.description.attributes += ConstraintAttributes.CenterX
+        self.description.attributes += .centerX
         return self
     }
     
     public var centerY: ConstraintMakerExtendable {
-        self.description.attributes += ConstraintAttributes.CenterY
+        self.description.attributes += .centerY
         return self
     }
     
+    @available(*, deprecated:0.40.0, message:"Use lastBaseline instead")
     public var baseline: ConstraintMakerExtendable {
-        self.description.attributes += ConstraintAttributes.Baseline
+        self.description.attributes += .lastBaseline
         return self
     }
     
-    @available(iOS 8.0, *)
+    public var lastBaseline: ConstraintMakerExtendable {
+        self.description.attributes += .lastBaseline
+        return self
+    }
+    
+    @available(iOS 8.0, OSX 10.11, *)
     public var firstBaseline: ConstraintMakerExtendable {
-        self.description.attributes += ConstraintAttributes.FirstBaseline
+        self.description.attributes += .firstBaseline
         return self
     }
     
     @available(iOS 8.0, *)
     public var leftMargin: ConstraintMakerExtendable {
-        self.description.attributes += ConstraintAttributes.LeftMargin
+        self.description.attributes += .leftMargin
         return self
     }
     
     @available(iOS 8.0, *)
     public var rightMargin: ConstraintMakerExtendable {
-        self.description.attributes += ConstraintAttributes.RightMargin
+        self.description.attributes += .rightMargin
         return self
     }
     
     @available(iOS 8.0, *)
     public var bottomMargin: ConstraintMakerExtendable {
-        self.description.attributes += ConstraintAttributes.BottomMargin
+        self.description.attributes += .bottomMargin
         return self
     }
     
     @available(iOS 8.0, *)
     public var leadingMargin: ConstraintMakerExtendable {
-        self.description.attributes += ConstraintAttributes.LeadingMargin
+        self.description.attributes += .leadingMargin
         return self
     }
     
     @available(iOS 8.0, *)
     public var trailingMargin: ConstraintMakerExtendable {
-        self.description.attributes += ConstraintAttributes.TrailingMargin
+        self.description.attributes += .trailingMargin
         return self
     }
     
     @available(iOS 8.0, *)
     public var centerXWithinMargins: ConstraintMakerExtendable {
-        self.description.attributes += ConstraintAttributes.CenterXWithinMargins
+        self.description.attributes += .centerXWithinMargins
         return self
     }
     
     @available(iOS 8.0, *)
     public var centerYWithinMargins: ConstraintMakerExtendable {
-        self.description.attributes += ConstraintAttributes.CenterYWithinMargins
+        self.description.attributes += .centerYWithinMargins
         return self
     }
     
     public var edges: ConstraintMakerExtendable {
-        self.description.attributes += ConstraintAttributes.Edges
+        self.description.attributes += .edges
         return self
     }
     public var size: ConstraintMakerExtendable {
-        self.description.attributes += ConstraintAttributes.Size
+        self.description.attributes += .size
         return self
     }
     
     @available(iOS 8.0, *)
     public var margins: ConstraintMakerExtendable {
-        self.description.attributes += ConstraintAttributes.Margins
+        self.description.attributes += .margins
         return self
     }
     
     @available(iOS 8.0, *)
     public var centerWithinMargins: ConstraintMakerExtendable {
-        self.description.attributes += ConstraintAttributes.CenterWithinMargins
+        self.description.attributes += .centerWithinMargins
         return self
     }
     

+ 6 - 0
Source/ConstraintMakerFinalizable.swift

@@ -36,6 +36,12 @@ public class ConstraintMakerFinalizable {
         self.description = description
     }
     
+    @discardableResult
+    public func labeled(_ label: String) -> ConstraintMakerFinalizable {
+        self.description.label = label
+        return self
+    }
+    
     public var constraint: Constraint {
         return self.description.constraint!
     }

+ 3 - 3
Source/ConstraintMakerRelatable.swift

@@ -41,7 +41,7 @@ public class ConstraintMakerRelatable {
         let constant: ConstraintConstantTarget
         
         if let other = other as? ConstraintItem {
-            guard other.attributes == ConstraintAttributes.None ||
+            guard other.attributes == ConstraintAttributes.none ||
                   other.attributes.layoutAttributes.count <= 1 ||
                   other.attributes.layoutAttributes == self.description.attributes.layoutAttributes else {
                 fatalError("Cannot constraint to multiple non identical attributes. (\(file), \(line))");
@@ -50,10 +50,10 @@ public class ConstraintMakerRelatable {
             related = other
             constant = 0.0
         } else if let other = other as? ConstraintView {
-            related = ConstraintItem(target: other, attributes: ConstraintAttributes.None)
+            related = ConstraintItem(target: other, attributes: ConstraintAttributes.none)
             constant = 0.0
         } else if let other = other as? ConstraintConstantTarget {
-            related = ConstraintItem(target: nil, attributes: ConstraintAttributes.None)
+            related = ConstraintItem(target: nil, attributes: ConstraintAttributes.none)
             constant = other
         } else {
             fatalError("Invalid constraint. (\(file), \(line))")

+ 32 - 33
Source/ConstraintView+Extensions.swift

@@ -30,117 +30,116 @@
 
 public extension ConstraintView {
     
-    @available(*, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
+    @available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.")
     public var snp_left: ConstraintItem { return self.snp.left }
     
-    @available(*, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
+    @available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.")
     public var snp_top: ConstraintItem { return self.snp.top }
     
-    @available(*, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
+    @available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.")
     public var snp_right: ConstraintItem { return self.snp.right }
     
-    @available(*, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
+    @available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.")
     public var snp_bottom: ConstraintItem { return self.snp.bottom }
     
-    @available(*, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
+    @available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.")
     public var snp_leading: ConstraintItem { return self.snp.leading }
     
-    @available(*, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
+    @available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.")
     public var snp_trailing: ConstraintItem { return self.snp.trailing }
     
-    @available(*, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
+    @available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.")
     public var snp_width: ConstraintItem { return self.snp.width }
     
-    @available(*, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
+    @available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.")
     public var snp_height: ConstraintItem { return self.snp.height }
     
-    @available(*, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
+    @available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.")
     public var snp_centerX: ConstraintItem { return self.snp.centerX }
     
-    @available(*, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
+    @available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.")
     public var snp_centerY: ConstraintItem { return self.snp.centerY }
     
-    @available(*, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
+    @available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.")
     public var snp_baseline: ConstraintItem { return self.snp.baseline }
     
-    @available(*, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
-    @available(iOS 8.0, OSX 10.11, *)
+    @available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.")
     public var snp_lastBaseline: ConstraintItem { return self.snp.lastBaseline }
     
-    @available(iOS, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
+    @available(iOS, deprecated:0.40.0, message:"Use newer snp.* syntax.")
     @available(iOS 8.0, OSX 10.11, *)
     public var snp_firstBaseline: ConstraintItem { return self.snp.firstBaseline }
     
-    @available(iOS, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
-    @available(iOS 8.0, OSX 10.11, *)
+    @available(iOS, deprecated:0.40.0, message:"Use newer snp.* syntax.")
+    @available(iOS 8.0, *)
     public var snp_leftMargin: ConstraintItem { return self.snp.leftMargin }
     
-    @available(iOS, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
+    @available(iOS, deprecated:0.40.0, message:"Use newer snp.* syntax.")
     @available(iOS 8.0, *)
     public var snp_topMargin: ConstraintItem { return self.snp.topMargin }
     
-    @available(iOS, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
+    @available(iOS, deprecated:0.40.0, message:"Use newer snp.* syntax.")
     @available(iOS 8.0, *)
     public var snp_rightMargin: ConstraintItem { return self.snp.rightMargin }
     
-    @available(iOS, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
+    @available(iOS, deprecated:0.40.0, message:"Use newer snp.* syntax.")
     @available(iOS 8.0, *)
     public var snp_bottomMargin: ConstraintItem { return self.snp.bottomMargin }
     
-    @available(iOS, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
+    @available(iOS, deprecated:0.40.0, message:"Use newer snp.* syntax.")
     @available(iOS 8.0, *)
     public var snp_leadingMargin: ConstraintItem { return self.snp.leadingMargin }
     
-    @available(iOS, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
+    @available(iOS, deprecated:0.40.0, message:"Use newer snp.* syntax.")
     @available(iOS 8.0, *)
     public var snp_trailingMargin: ConstraintItem { return self.snp.trailingMargin }
     
-    @available(iOS, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
+    @available(iOS, deprecated:0.40.0, message:"Use newer snp.* syntax.")
     @available(iOS 8.0, *)
     public var snp_centerXWithinMargins: ConstraintItem { return self.snp.centerXWithinMargins }
     
-    @available(iOS, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
+    @available(iOS, deprecated:0.40.0, message:"Use newer snp.* syntax.")
     @available(iOS 8.0, *)
     public var snp_centerYWithinMargins: ConstraintItem { return self.snp.centerYWithinMargins }
     
-    @available(*, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
+    @available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.")
     public var snp_edges: ConstraintItem { return self.snp.edges }
     
-    @available(*, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
+    @available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.")
     public var snp_size: ConstraintItem { return self.snp.size }
     
-    @available(*, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
+    @available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.")
     public var snp_center: ConstraintItem { return self.snp.center }
     
-    @available(iOS, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
+    @available(iOS, deprecated:0.40.0, message:"Use newer snp.* syntax.")
     @available(iOS 8.0, *)
     public var snp_margins: ConstraintItem { return self.snp.margins }
     
-    @available(iOS, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
+    @available(iOS, deprecated:0.40.0, message:"Use newer snp.* syntax.")
     @available(iOS 8.0, *)
     public var snp_centerWithinMargins: ConstraintItem { return self.snp.centerWithinMargins }
     
-    @available(*, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
+    @available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.")
     public func snp_prepareConstraints(_ closure: @noescape(make: ConstraintMaker) -> Void) -> [Constraint] {
         return self.snp.prepareConstraints(closure)
     }
     
-    @available(*, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
+    @available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.")
     public func snp_makeConstraints(_ closure: @noescape(make: ConstraintMaker) -> Void) {
         self.snp.makeConstraints(closure)
     }
     
-    @available(*, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
+    @available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.")
     public func snp_remakeConstraints(_ closure: @noescape(make: ConstraintMaker) -> Void) {
         self.snp.remakeConstraints(closure)
     }
     
-    @available(*, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
+    @available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.")
     public func snp_updateConstraints(_ closure: @noescape(make: ConstraintMaker) -> Void) {
         self.snp.updateConstraints(closure)
     }
     
-    @available(*, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
+    @available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.")
     public func snp_removeConstraints() {
         self.snp.removeConstraints()
     }

+ 4 - 4
Source/ConstraintViewController+Extensions.swift

@@ -27,22 +27,22 @@
 
     public extension ConstraintViewController {
         
-        @available(iOS, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
+        @available(iOS, deprecated:0.40.0, message:"Use newer snp.* syntax.")
         public var topLayoutGuideTop: ConstraintItem {
             return self.snp.topLayoutGuideTop
         }
         
-        @available(iOS, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
+        @available(iOS, deprecated:0.40.0, message:"Use newer snp.* syntax.")
         public var topLayoutGuideBottom: ConstraintItem {
             return self.snp.topLayoutGuideBottom
         }
         
-        @available(iOS, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
+        @available(iOS, deprecated:0.40.0, message:"Use newer snp.* syntax.")
         public var bottomLayoutGuideTop: ConstraintItem {
             return self.snp.bottomLayoutGuideTop
         }
         
-        @available(iOS, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
+        @available(iOS, deprecated:0.40.0, message:"Use newer snp.* syntax.")
         public var bottomLayoutGuideBottom: ConstraintItem {
             return self.snp.bottomLayoutGuideBottom
         }

+ 8 - 8
Source/ConstraintViewControllerDSL.swift

@@ -27,24 +27,24 @@
 
     public struct ConstraintViewControllerDSL {
         
-        @available(iOS 7.0, *)
+        @available(iOS 8.0, *)
         public var topLayoutGuideTop: ConstraintItem {
-            return ConstraintItem(target: self.viewController.topLayoutGuide, attributes: ConstraintAttributes.Top)
+            return ConstraintItem(target: self.viewController.topLayoutGuide, attributes: ConstraintAttributes.top)
         }
         
-        @available(iOS 7.0, *)
+        @available(iOS 8.0, *)
         public var topLayoutGuideBottom: ConstraintItem {
-            return ConstraintItem(target: self.viewController.topLayoutGuide, attributes: ConstraintAttributes.Bottom)
+            return ConstraintItem(target: self.viewController.topLayoutGuide, attributes: ConstraintAttributes.bottom)
         }
         
-        @available(iOS 7.0, *)
+        @available(iOS 8.0, *)
         public var bottomLayoutGuideTop: ConstraintItem {
-            return ConstraintItem(target: self.viewController.bottomLayoutGuide, attributes: ConstraintAttributes.Top)
+            return ConstraintItem(target: self.viewController.bottomLayoutGuide, attributes: ConstraintAttributes.top)
         }
         
-        @available(iOS 7.0, *)
+        @available(iOS 8.0, *)
         public var bottomLayoutGuideBottom: ConstraintItem {
-            return ConstraintItem(target: self.viewController.bottomLayoutGuide, attributes: ConstraintAttributes.Bottom)
+            return ConstraintItem(target: self.viewController.bottomLayoutGuide, attributes: ConstraintAttributes.bottom)
         }
         
         internal let viewController: ConstraintViewController

+ 39 - 38
Source/ConstraintViewDSL.swift

@@ -31,122 +31,123 @@
 public struct ConstraintViewDSL {
     
     public var left: ConstraintItem {
-        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.Left)
+        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.left)
     }
     
     public var top: ConstraintItem {
-        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.Top)
+        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.top)
     }
     
     public var right: ConstraintItem {
-        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.Right)
+        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.right)
     }
     
     public var bottom: ConstraintItem {
-        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.Bottom)
+        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.bottom)
     }
     
     public var leading: ConstraintItem {
-        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.Leading)
+        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.leading)
     }
     
     public var trailing: ConstraintItem {
-        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.Trailing)
+        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.trailing)
     }
     
     public var width: ConstraintItem {
-        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.Width)
+        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.width)
     }
     
     public var height: ConstraintItem {
-        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.Height)
+        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.height)
     }
     
     public var centerX: ConstraintItem {
-        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.CenterX)
+        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.centerX)
     }
     
     public var centerY: ConstraintItem {
-        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.CenterY)
+        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.centerY)
     }
     
-    @available(*, deprecated:0.40.0, message:"Please use migrated .lastBaseline")
+    @available(*, deprecated:0.40.0, message:"Use .lastBaseline instead")
     public var baseline: ConstraintItem {
-        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.Baseline)
+        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.lastBaseline)
     }
     
     @available(iOS 8.0, OSX 10.11, *)
     public var lastBaseline: ConstraintItem {
-        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.Baseline)
+        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.lastBaseline)
     }
     
     @available(iOS 8.0, OSX 10.11, *)
     public var firstBaseline: ConstraintItem {
-        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.FirstBaseline)
+        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.firstBaseline)
     }
     
     @available(iOS 8.0, *)
     public var leftMargin: ConstraintItem {
-        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.LeftMargin)
+        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.leftMargin)
     }
     
     @available(iOS 8.0, *)
     public var topMargin: ConstraintItem {
-        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.TopMargin)
+        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.topMargin)
     }
     
     @available(iOS 8.0, *)
     public var rightMargin: ConstraintItem {
-        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.RightMargin)
+        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.rightMargin)
     }
     
     @available(iOS 8.0, *)
     public var bottomMargin: ConstraintItem {
-        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.BottomMargin)
+        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.bottomMargin)
     }
     
     @available(iOS 8.0, *)
     public var leadingMargin: ConstraintItem {
-        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.LeadingMargin)
+        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.leadingMargin)
     }
     
     @available(iOS 8.0, *)
     public var trailingMargin: ConstraintItem {
-        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.TrailingMargin)
+        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.trailingMargin)
     }
     
     @available(iOS 8.0, *)
     public var centerXWithinMargins: ConstraintItem {
-        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.CenterXWithinMargins)
+        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.centerXWithinMargins)
     }
     
     @available(iOS 8.0, *)
     public var centerYWithinMargins: ConstraintItem {
-        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.CenterYWithinMargins)
+        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.centerYWithinMargins)
     }
     
     public var edges: ConstraintItem {
-        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.Edges)
+        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.edges)
     }
     
     public var size: ConstraintItem {
-        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.Size)
+        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.size)
     }
     
     public var center: ConstraintItem {
-        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.Center)
+        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.center)
     }
     
     @available(iOS 8.0, *)
     public var margins: ConstraintItem {
-        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.Margins)
+        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.margins)
     }
     
     @available(iOS 8.0, *)
     public var centerWithinMargins: ConstraintItem {
-        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.CenterWithinMargins)
+        return ConstraintItem(target: self.view, attributes: ConstraintAttributes.centerWithinMargins)
     }
     
+    @discardableResult
     public func prepareConstraints(_ closure: @noescape (make: ConstraintMaker) -> Void) -> [Constraint] {
         return ConstraintMaker.prepareConstraints(view: self.view, closure: closure)
     }
@@ -216,23 +217,23 @@ public struct ConstraintViewDSL {
     
     internal init(view: ConstraintView) {
         self.view = view
+        
     }
     
-    internal var installedLayoutConstraints: [LayoutConstraint] {
-        return objc_getAssociatedObject(self.view, &installedLayoutConstraintsKey) as? [LayoutConstraint] ?? []
+    internal var layoutConstraints: [LayoutConstraint] {
+        return objc_getAssociatedObject(self.view, &layoutConstraintsKey) as? [LayoutConstraint] ?? []
     }
     
-    internal func appendInstalledLayoutConstraints(_ layoutConstraints: [LayoutConstraint]) {
-        var newValue = self.installedLayoutConstraints
-        newValue += layoutConstraints
-        objc_setAssociatedObject(self.view, &installedLayoutConstraintsKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
+    internal func add(layoutConstraints: [LayoutConstraint]) {
+        let merged = self.layoutConstraints + layoutConstraints
+        objc_setAssociatedObject(self.view, &layoutConstraintsKey, merged, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
     }
     
-    internal func removeInstalledLayoutConstraints(_ layoutConstraints: [LayoutConstraint]) {
-        let newValue = self.installedLayoutConstraints.filter { !layoutConstraints.contains($0) }
-        objc_setAssociatedObject(self.view, &installedLayoutConstraintsKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
+    internal func remove(layoutConstraints: [LayoutConstraint]) {
+        let merged = self.layoutConstraints.filter { !layoutConstraints.contains($0) }
+        objc_setAssociatedObject(self.view, &layoutConstraintsKey, merged, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
     }
+    
 }
-
 private var labelKey: UInt8 = 0
-private var installedLayoutConstraintsKey: UInt8 = 0
+private var layoutConstraintsKey: UInt8 = 0

+ 10 - 2
Source/LayoutConstraint.swift

@@ -30,8 +30,16 @@
 
 public class LayoutConstraint: NSLayoutConstraint {
     
-    internal var constraint: Constraint? = nil
-    public var label: String? = nil
+    public var label: String? {
+        get {
+            return self.identifier
+        }
+        set {
+            self.identifier = newValue
+        }
+    }
+    
+    internal var constraint: Constraint! = nil
     
 }
 

+ 284 - 1
Tests/Tests.swift

@@ -13,7 +13,7 @@ extension View {
 #endif
 
 import XCTest
-import SnapKit
+@testable import SnapKit
 
 class SnapKitTests: XCTestCase {
     
@@ -29,4 +29,287 @@ class SnapKitTests: XCTestCase {
         super.tearDown()
     }
     
+    func testLayoutGuideConstraints() {
+        #if os(iOS) || os(tvOS)
+            let vc = UIViewController()
+            vc.view = UIView(frame: CGRect(x: 0, y: 0, width: 300, height: 300))
+            
+            vc.view.addSubview(self.container)
+            
+            self.container.snp.makeConstraints { (make) -> Void in
+                make.top.equalTo(vc.snp.topLayoutGuideBottom)
+                make.bottom.equalTo(vc.snp.bottomLayoutGuideTop)
+            }
+            
+            XCTAssertEqual(vc.view.snp_constraints.count, 6, "Should have 6 constraints installed")
+        #endif
+    }
+    
+    func testMakeConstraints() {
+        let v1 = View()
+        let v2 = View()
+        self.container.addSubview(v1)
+        self.container.addSubview(v2)
+        
+        v1.snp.makeConstraints { (make) -> Void in
+            make.top.equalTo(v2.snp.top).offset(50)
+            make.left.equalTo(v2.snp.top).offset(50)
+            return
+        }
+        
+        XCTAssertEqual(self.container.snp_constraints.count, 2, "Should have 2 constraints installed")
+        
+        v2.snp.makeConstraints { (make) -> Void in
+            make.edges.equalTo(v1)
+            return
+        }
+        
+        XCTAssertEqual(self.container.snp_constraints.count, 6, "Should have 6 constraints installed")
+        
+    }
+    
+    func testUpdateConstraints() {
+        let v1 = View()
+        let v2 = View()
+        self.container.addSubview(v1)
+        self.container.addSubview(v2)
+        
+        print(v1)
+        
+        v1.snp.makeConstraints { (make) -> Void in
+            make.top.equalTo(v2.snp.top).offset(50)
+            make.left.equalTo(v2.snp.top).offset(50)
+            return
+        }
+        
+        XCTAssertEqual(self.container.snp_constraints.count, 2, "Should have 2 constraints installed")
+        
+        v1.snp.updateConstraints { (make) -> Void in
+            make.top.equalTo(v2.snp.top).offset(15)
+            return
+        }
+        
+        XCTAssertEqual(self.container.snp_constraints.count, 2, "Should still have 2 constraints installed")
+        
+    }
+    
+    func testRemakeConstraints() {
+        let v1 = View()
+        let v2 = View()
+        self.container.addSubview(v1)
+        self.container.addSubview(v2)
+        
+        v1.snp.makeConstraints { (make) -> Void in
+            make.top.equalTo(v2.snp.top).offset(50)
+            make.left.equalTo(v2.snp.top).offset(50)
+            return
+        }
+        
+        XCTAssertEqual(self.container.snp_constraints.count, 2, "Should have 2 constraints installed")
+        
+        v1.snp.remakeConstraints { (make) -> Void in
+            make.edges.equalTo(v2)
+            return
+        }
+        
+        XCTAssertEqual(self.container.snp_constraints.count, 4, "Should have 4 constraints installed")
+        
+    }
+    
+    func testRemoveConstraints() {
+        let v1 = View()
+        let v2 = View()
+        self.container.addSubview(v1)
+        self.container.addSubview(v2)
+        
+        v1.snp.makeConstraints { (make) -> Void in
+            make.top.equalTo(v2.snp.top).offset(50)
+            make.left.equalTo(v2.snp.top).offset(50)
+            return
+        }
+        
+        XCTAssertEqual(self.container.snp_constraints.count, 2, "Should have 2 constraints installed")
+        
+        v1.snp.removeConstraints()
+        
+        XCTAssertEqual(self.container.snp_constraints.count, 0, "Should have 0 constraints installed")
+        
+    }
+    
+    func testPrepareConstraints() {
+        let v1 = View()
+        let v2 = View()
+        self.container.addSubview(v1)
+        self.container.addSubview(v2)
+        
+        let constraints = v1.snp.prepareConstraints { (make) -> Void in
+            make.edges.equalTo(v2)
+            return
+        }
+        
+        XCTAssertEqual(self.container.snp_constraints.count, 0, "Should have 0 constraints installed")
+        
+        for constraint in constraints {
+            constraint.activate()
+        }
+        
+        XCTAssertEqual(self.container.snp_constraints.count, 4, "Should have 4 constraints installed")
+        
+        for constraint in constraints {
+            constraint.deactivate()
+        }
+        
+        XCTAssertEqual(self.container.snp_constraints.count, 0, "Should have 0 constraints installed")
+        
+    }
+    
+    func testReactivateConstraints() {
+        let v1 = View()
+        let v2 = View()
+        self.container.addSubview(v1)
+        self.container.addSubview(v2)
+        
+        let constraints = v1.snp.prepareConstraints { (make) -> Void in
+            make.edges.equalTo(v2)
+            return
+        }
+        
+        
+        XCTAssertEqual(self.container.snp_constraints.count, 0, "Should have 0 constraints installed")
+        
+        for constraint in constraints {
+            constraint.activate()
+        }
+        
+        XCTAssertEqual(self.container.snp_constraints.count, 4, "Should have 4 constraints installed")
+        
+        for constraint in constraints {
+            constraint.deactivate()
+        }
+        
+        XCTAssertEqual(self.container.snp_constraints.count, 0, "Should have 0 constraints installed")
+    }
+    
+    func testActivateDeactivateConstraints() {
+        let v1 = View()
+        let v2 = View()
+        self.container.addSubview(v1)
+        self.container.addSubview(v2)
+        
+        var c1: Constraint? = nil
+        var c2: Constraint? = nil
+        
+        v1.snp.prepareConstraints { (make) -> Void in
+            c1 = make.top.equalTo(v2.snp.top).offset(50).constraint
+            c2 = make.left.equalTo(v2.snp.top).offset(50).constraint
+            return
+        }
+        
+        XCTAssertEqual(self.container.snp_constraints.count, 0, "Should have 0 constraints")
+        
+        c1?.activate()
+        c2?.activate()
+        
+        XCTAssertEqual(self.container.snp_constraints.count, 2, "Should have 2 constraints")
+        
+        c1?.deactivate()
+        c2?.deactivate()
+        
+        XCTAssertEqual(self.container.snp_constraints.count, 0, "Should have 0 constraints")
+        
+        c1?.activate()
+        c2?.activate()
+        
+        XCTAssertEqual(self.container.snp_constraints.count, 2, "Should have 2 constraints")
+        
+    }
+    
+    func testSizeConstraints() {
+        let view = View()
+        self.container.addSubview(view)
+        
+        view.snp.makeConstraints { (make) -> Void in
+            make.size.equalTo(CGSize(width: 50, height: 50))
+            make.left.top.equalTo(self.container)
+        }
+        
+        XCTAssertEqual(view.snp_constraints.count, 2, "Should have 2 constraints")
+        
+        XCTAssertEqual(self.container.snp_constraints.count, 2, "Should have 2 constraints")
+        
+        
+        let constraints = view.snp_constraints as! [NSLayoutConstraint]
+        
+        XCTAssertEqual(constraints[0].firstAttribute.rawValue, NSLayoutAttribute.width.rawValue, "Should be width")
+        XCTAssertEqual(constraints[1].firstAttribute.rawValue, NSLayoutAttribute.height.rawValue, "Should be height")
+        XCTAssertEqual(constraints[0].constant, 50, "Should be 50")
+        XCTAssertEqual(constraints[1].constant, 50, "Should be 50")
+    }
+    
+    func testConstraintIdentifier() {
+        let identifier = "Test-Identifier"
+        let view = View()
+        self.container.addSubview(view)
+        
+        view.snp.makeConstraints { (make) -> Void in
+            make.top.equalTo(self.container.snp.top).labeled(identifier)
+        }
+        
+        let constraints = container.snp_constraints as! [NSLayoutConstraint]
+        XCTAssertEqual(constraints[0].identifier, identifier, "Identifier should be 'Test'")
+    }
+//
+////    func testSuperviewConstraints() {
+////        let view = View()
+////        
+////        container.addSubview(view)
+////        
+////        view.snp.makeConstraints { (make) -> Void in
+////            make.top.equalToSuperview().inset(10)
+////            make.bottom.equalToSuperview().inset(10)
+////        }
+////        
+////        XCTAssertEqual(container.snp_constraints.count, 2, "Should have 2 constraints")
+////        
+////        let constraints = container.snp_constraints as! [NSLayoutConstraint]
+////        
+////        XCTAssertEqual(constraints[0].firstAttribute, NSLayoutAttribute.top, "Should be top")
+////        XCTAssertEqual(constraints[1].firstAttribute, NSLayoutAttribute.bottom, "Should be bottom")
+////        
+////        XCTAssertEqual(constraints[0].secondAttribute, NSLayoutAttribute.top, "Should be top")
+////        XCTAssertEqual(constraints[1].secondAttribute, NSLayoutAttribute.bottom, "Should be bottom")
+////        
+////        XCTAssertEqual(constraints[0].firstItem as? View, view, "Should be added subview")
+////        XCTAssertEqual(constraints[1].firstItem as? View, view, "Should be added subview")
+////        
+////        XCTAssertEqual(constraints[0].secondItem as? View, container, "Should be containerView")
+////        XCTAssertEqual(constraints[1].secondItem as? View, container, "Should be containerView")
+////        
+////        XCTAssertEqual(constraints[0].constant, 10, "Should be 10")
+////        XCTAssertEqual(constraints[1].constant, -10, "Should be 10")
+////    }
+//    
+////    func testNativeConstraints() {
+////        let view = View()
+////        
+////        container.addSubview(view)
+////        
+////        var topNativeConstraints: [LayoutConstraint]!
+////        var topNativeConstraint: LayoutConstraint?
+////        var sizeNativeConstraints: [LayoutConstraint]!
+////        view.snp_makeConstraints { (make) -> Void in
+////            let topConstraint = make.top.equalToSuperview().inset(10).constraint
+////            topNativeConstraints = topConstraint.layoutConstraints
+////            topNativeConstraint = topConstraint.layoutConstraints.first
+////            let sizeConstraints = make.size.equalTo(50).constraint
+////            sizeNativeConstraints = sizeConstraints.layoutConstraints
+////        }
+////        
+////        XCTAssertEqual(topNativeConstraints.count, 1, "make.top should creates one native constraint")
+////        XCTAssertEqual(topNativeConstraint?.constant, 10, "topNativeConstraint.constant is set to 10")
+////        XCTAssertEqual(sizeNativeConstraints.count, 2, "make.tosize should create two native constraint")
+////        XCTAssertEqual(sizeNativeConstraints[0].constant, 50, "sizeNativeConstraints should set size[0] to 50")
+////        XCTAssertEqual(sizeNativeConstraints[1].constant, 50, "sizeNativeConstraints should set size[1] to 50")
+////    }
+    
 }