Sfoglia il codice sorgente

Begin support for LayoutGuide constraint maker

Robert Payne 9 anni fa
parent
commit
dc304472aa

+ 4 - 0
SnapKit.xcodeproj/project.pbxproj

@@ -33,6 +33,7 @@
 		EE235FC31C5785DC00C08960 /* ConstraintLayoutSupportDSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE235FBF1C5785DC00C08960 /* ConstraintLayoutSupportDSL.swift */; };
 		EE235FC81C5785E200C08960 /* ConstraintView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE235FC61C5785E200C08960 /* ConstraintView+Extensions.swift */; };
 		EE4910991B19A40200A54F1F /* SnapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EEBCC9D819CC627D0083B827 /* SnapKit.framework */; };
+		EE6898CB1DA7B3A100D47F33 /* LayoutConstraintItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE6898CA1DA7B3A100D47F33 /* LayoutConstraintItem.swift */; };
 		EECDB3741AC0C9B6006BBC11 /* SnapKit.h in Headers */ = {isa = PBXBuildFile; fileRef = EECDB3661AC0C95C006BBC11 /* SnapKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		EECDB3931AC0CB52006BBC11 /* Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EECDB36A1AC0C95C006BBC11 /* Tests.swift */; };
 		EEF68F9E1D78492400980C26 /* ConstraintLayoutGuideDSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEF68F9D1D78492400980C26 /* ConstraintLayoutGuideDSL.swift */; };
@@ -70,6 +71,7 @@
 		EE235FBE1C5785DC00C08960 /* ConstraintViewDSL.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConstraintViewDSL.swift; sourceTree = "<group>"; };
 		EE235FBF1C5785DC00C08960 /* ConstraintLayoutSupportDSL.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConstraintLayoutSupportDSL.swift; sourceTree = "<group>"; };
 		EE235FC61C5785E200C08960 /* ConstraintView+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ConstraintView+Extensions.swift"; sourceTree = "<group>"; };
+		EE6898CA1DA7B3A100D47F33 /* LayoutConstraintItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LayoutConstraintItem.swift; sourceTree = "<group>"; };
 		EE94F6081AC0F10A008767FF /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
 		EE94F60A1AC0F10F008767FF /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/System/Library/Frameworks/AppKit.framework; sourceTree = DEVELOPER_DIR; };
 		EEBCC9D819CC627D0083B827 /* SnapKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SnapKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -184,6 +186,7 @@
 				EE235F6A1C5785C600C08960 /* ConstraintAttributes.swift */,
 				EE235F6B1C5785C600C08960 /* ConstraintItem.swift */,
 				EE235F6C1C5785C600C08960 /* LayoutConstraint.swift */,
+				EE6898CA1DA7B3A100D47F33 /* LayoutConstraintItem.swift */,
 			);
 			name = Models;
 			sourceTree = "<group>";
@@ -372,6 +375,7 @@
 				EE235F761C5785C600C08960 /* ConstraintConfig.swift in Sources */,
 				EE235F6D1C5785C600C08960 /* Constraint.swift in Sources */,
 				EE235F791C5785C600C08960 /* ConstraintView.swift in Sources */,
+				EE6898CB1DA7B3A100D47F33 /* LayoutConstraintItem.swift in Sources */,
 				EE235FB21C5785D400C08960 /* ConstraintMakerPriortizable.swift in Sources */,
 				EE235F8B1C5785C600C08960 /* LayoutConstraint.swift in Sources */,
 				EE235FA31C5785CE00C08960 /* ConstraintInsetTarget.swift in Sources */,

+ 8 - 8
Source/Constraint.swift

@@ -73,7 +73,7 @@ public class Constraint {
         let layoutToAttributes = self.to.attributes.layoutAttributes
         
         // get layout from
-        let layoutFrom: ConstraintView = self.from.view!
+        let layoutFrom = self.from.layoutConstraintItem!
         
         // get relation
         let layoutRelation = self.relation.layoutRelation
@@ -247,12 +247,12 @@ public class Constraint {
     }
     
     internal func activateIfNeeded(updatingExisting: Bool = false) {
-        guard let view = self.from.view else {
-            print("WARNING: SnapKit failed to get from view from constraint. Activate will be a no-op.")
+        guard let item = self.from.layoutConstraintItem else {
+            print("WARNING: SnapKit failed to get from item from constraint. Activate will be a no-op.")
             return
         }
         let layoutConstraints = self.layoutConstraints
-        let existingLayoutConstraints = view.snp.constraints.map({ $0.layoutConstraints }).reduce([]) { $0 + $1 }
+        let existingLayoutConstraints = item.constraints.map({ $0.layoutConstraints }).reduce([]) { $0 + $1 }
         
         if updatingExisting {
             for layoutConstraint in layoutConstraints {
@@ -266,17 +266,17 @@ public class Constraint {
             }
         } else {
             NSLayoutConstraint.activate(layoutConstraints)
-            view.snp.add(constraints: [self])
+            item.add(constraints: [self])
         }
     }
     
     internal func deactivateIfNeeded() {
-        guard let view = self.from.view else {
-            print("WARNING: SnapKit failed to get from view from constraint. Deactivate will be a no-op.")
+        guard let item = self.from.layoutConstraintItem else {
+            print("WARNING: SnapKit failed to get from item from constraint. Deactivate will be a no-op.")
             return
         }
         let layoutConstraints = self.layoutConstraints
         NSLayoutConstraint.deactivate(layoutConstraints)
-        view.snp.remove(constraints: [self])
+        item.remove(constraints: [self])
     }
 }

+ 1 - 1
Source/ConstraintAttributes.swift

@@ -28,7 +28,7 @@
 #endif
 
 
-internal struct ConstraintAttributes: OptionSet {
+internal struct ConstraintAttributes : OptionSet {
     
     internal init(rawValue: UInt) {
         self.rawValue = rawValue

+ 4 - 4
Source/ConstraintDescription.swift

@@ -30,7 +30,7 @@
 
 public class ConstraintDescription {
     
-    internal let view: ConstraintView
+    internal let item: LayoutConstraintItem
     internal var attributes: ConstraintAttributes
     internal var relation: ConstraintRelation? = nil
     internal var sourceLocation: (String, UInt)? = nil
@@ -45,7 +45,7 @@ public class ConstraintDescription {
               let sourceLocation = self.sourceLocation else {
             return nil
         }
-        let from = ConstraintItem(target: self.view, attributes: self.attributes)
+        let from = ConstraintItem(target: self.item as AnyObject, attributes: self.attributes)
         
         return Constraint(
             from: from,
@@ -61,8 +61,8 @@ public class ConstraintDescription {
     
     // MARK: Initialization
     
-    internal init(view: ConstraintView, attributes: ConstraintAttributes) {
-        self.view = view
+    internal init(item: LayoutConstraintItem, attributes: ConstraintAttributes) {
+        self.item = item
         self.attributes = attributes
     }
     

+ 3 - 3
Source/ConstraintItem.swift

@@ -28,7 +28,7 @@
 #endif
 
 
-public class ConstraintItem: Equatable {
+public class ConstraintItem : Equatable {
     
     internal weak var target: AnyObject?
     internal let attributes: ConstraintAttributes
@@ -38,8 +38,8 @@ public class ConstraintItem: Equatable {
         self.attributes = attributes
     }
     
-    internal var view: ConstraintView? {
-        return self.target as? ConstraintView
+    internal var layoutConstraintItem: LayoutConstraintItem? {
+        return self.target as? LayoutConstraintItem
     }
     
 }

+ 18 - 18
Source/ConstraintMaker.swift

@@ -143,22 +143,22 @@ public class ConstraintMaker {
         return self.makeExtendableWithAttributes(.centerWithinMargins)
     }
     
-    private let view: ConstraintView
+    private let item: LayoutConstraintItem
     private var descriptions = [ConstraintDescription]()
     
-    internal init(view: ConstraintView) {
-        self.view = view
-        self.view.translatesAutoresizingMaskIntoConstraints = false
+    internal init(item: LayoutConstraintItem) {
+        self.item = item
+        self.item.prepare()
     }
     
     internal func makeExtendableWithAttributes(_ attributes: ConstraintAttributes) -> ConstraintMakerExtendable {
-        let description = ConstraintDescription(view: self.view, attributes: attributes)
+        let description = ConstraintDescription(item: self.item, attributes: attributes)
         self.descriptions.append(description)
         return ConstraintMakerExtendable(description)
     }
     
-    internal static func prepareConstraints(view: ConstraintView, closure: (_ make: ConstraintMaker) -> Void) -> [Constraint] {
-        let maker = ConstraintMaker(view: view)
+    internal static func prepareConstraints(item: LayoutConstraintItem, closure: (_ make: ConstraintMaker) -> Void) -> [Constraint] {
+        let maker = ConstraintMaker(item: item)
         closure(maker)
         let constraints = maker.descriptions
             .map { $0.constraint }
@@ -167,8 +167,8 @@ public class ConstraintMaker {
         return constraints
     }
     
-    internal static func makeConstraints(view: ConstraintView, closure: (_ make: ConstraintMaker) -> Void) {
-        let maker = ConstraintMaker(view: view)
+    internal static func makeConstraints(item: LayoutConstraintItem, closure: (_ make: ConstraintMaker) -> Void) {
+        let maker = ConstraintMaker(item: item)
         closure(maker)
         let constraints = maker.descriptions
             .map { $0.constraint }
@@ -179,18 +179,18 @@ public class ConstraintMaker {
         }
     }
     
-    internal static func remakeConstraints(view: ConstraintView, closure: (_ make: ConstraintMaker) -> Void) {
-        self.removeConstraints(view: view)
-        self.makeConstraints(view: view, closure: closure)
+    internal static func remakeConstraints(item: LayoutConstraintItem, closure: (_ make: ConstraintMaker) -> Void) {
+        self.removeConstraints(item: item)
+        self.makeConstraints(item: item, closure: closure)
     }
     
-    internal static func updateConstraints(view: ConstraintView, closure: (_ make: ConstraintMaker) -> Void) {
-        guard view.snp.constraints.count > 0 else {
-            self.makeConstraints(view: view, closure: closure)
+    internal static func updateConstraints(item: LayoutConstraintItem, closure: (_ make: ConstraintMaker) -> Void) {
+        guard item.constraints.count > 0 else {
+            self.makeConstraints(item: item, closure: closure)
             return
         }
         
-        let maker = ConstraintMaker(view: view)
+        let maker = ConstraintMaker(item: item)
         closure(maker)
         let constraints = maker.descriptions
             .map { $0.constraint }
@@ -201,8 +201,8 @@ public class ConstraintMaker {
         }
     }
     
-    internal static func removeConstraints(view: ConstraintView) {
-        let constraints = view.snp.constraints
+    internal static func removeConstraints(item: LayoutConstraintItem) {
+        let constraints = item.constraints
         for constraint in constraints {
             constraint.deactivateIfNeeded()
         }

+ 3 - 3
Source/ConstraintMakerRelatable.swift

@@ -76,7 +76,7 @@ public class ConstraintMakerRelatable {
     
     @discardableResult
     public func equalToSuperview(_ file: String = #file, _ line: UInt = #line) -> ConstraintMakerEditable {
-        guard let other = self.description.view.superview else {
+        guard let other = self.description.item.superview else {
             fatalError("Expected superview but found nil when attempting make constraint `equalToSuperview`.")
         }
         return self.relatedTo(other, relation: .equal, file: file, line: line)
@@ -89,7 +89,7 @@ public class ConstraintMakerRelatable {
     
     @discardableResult
     public func lessThanOrEqualToSuperview(_ file: String = #file, _ line: UInt = #line) -> ConstraintMakerEditable {
-        guard let other = self.description.view.superview else {
+        guard let other = self.description.item.superview else {
             fatalError("Expected superview but found nil when attempting make constraint `lessThanOrEqualToSuperview`.")
         }
         return self.relatedTo(other, relation: .lessThanOrEqual, file: file, line: line)
@@ -102,7 +102,7 @@ public class ConstraintMakerRelatable {
     
     @discardableResult
     public func greaterThanOrEqualToSuperview(_ file: String = #file, line: UInt = #line) -> ConstraintMakerEditable {
-        guard let other = self.description.view.superview else {
+        guard let other = self.description.item.superview else {
             fatalError("Expected superview but found nil when attempting make constraint `greaterThanOrEqualToSuperview`.")
         }
         return self.relatedTo(other, relation: .greaterThanOrEqual, file: file, line: line)

+ 1 - 1
Source/ConstraintRelation.swift

@@ -28,7 +28,7 @@
 #endif
 
 
-internal enum ConstraintRelation: Int {
+internal enum ConstraintRelation : Int {
     case equal = 1
     case lessThanOrEqual
     case greaterThanOrEqual

+ 5 - 39
Source/ConstraintViewDSL.swift

@@ -32,27 +32,25 @@ public struct ConstraintViewDSL: ConstraintAttributesDSL {
     
     @discardableResult
     public func prepareConstraints(_ closure: (_ make: ConstraintMaker) -> Void) -> [Constraint] {
-        return ConstraintMaker.prepareConstraints(view: self.view, closure: closure)
+        return ConstraintMaker.prepareConstraints(item: self.view, closure: closure)
     }
     
     public func makeConstraints(_ closure: (_ make: ConstraintMaker) -> Void) {
-        ConstraintMaker.makeConstraints(view: self.view, closure: closure)
+        ConstraintMaker.makeConstraints(item: self.view, closure: closure)
     }
     
     public func remakeConstraints(_ closure: (_ make: ConstraintMaker) -> Void) {
-        ConstraintMaker.remakeConstraints(view: self.view, closure: closure)
+        ConstraintMaker.remakeConstraints(item: self.view, closure: closure)
     }
     
     public func updateConstraints(_ closure: (_ make: ConstraintMaker) -> Void) {
-        ConstraintMaker.updateConstraints(view: self.view, closure: closure)
+        ConstraintMaker.updateConstraints(item: self.view, closure: closure)
     }
     
     public func removeConstraints() {
-        ConstraintMaker.removeConstraints(view: self.view)
+        ConstraintMaker.removeConstraints(item: self.view)
     }
     
-    
-    
     public var contentHuggingHorizontalPriority: Float {
         get {
             return self.view.contentHuggingPriority(for: .horizontal)
@@ -100,36 +98,4 @@ public struct ConstraintViewDSL: ConstraintAttributesDSL {
         
     }
     
-    internal var constraints: [Constraint] {
-        return self.constraintsHashTable.allObjects
-    }
-    
-    internal func add(constraints: [Constraint]) {
-        let hashTable = self.constraintsHashTable
-        for constraint in constraints {
-            hashTable.add(constraint)
-        }
-    }
-    
-    internal func remove(constraints: [Constraint]) {
-        let hashTable = self.constraintsHashTable
-        for constraint in constraints {
-            hashTable.remove(constraint)
-        }
-    }
-    
-    private var constraintsHashTable: NSHashTable<Constraint> {
-        let constraints: NSHashTable<Constraint>
-        
-        if let existing = objc_getAssociatedObject(self.view, &constraintsKey) as? NSHashTable<Constraint> {
-            constraints = existing
-        } else {
-            constraints = NSHashTable<Constraint>()
-            objc_setAssociatedObject(self.view, &constraintsKey, constraints, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
-        }
-        return constraints
-        
-    }
-    
 }
-private var constraintsKey: UInt8 = 0

+ 1 - 1
Source/LayoutConstraint.swift

@@ -28,7 +28,7 @@
 #endif
 
 
-public class LayoutConstraint: NSLayoutConstraint {
+public class LayoutConstraint : NSLayoutConstraint {
     
     public var label: String? {
         get {

+ 92 - 0
Source/LayoutConstraintItem.swift

@@ -0,0 +1,92 @@
+//
+//  SnapKit
+//
+//  Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
+//
+//  Permission is hereby granted, free of charge, to any person obtaining a copy
+//  of this software and associated documentation files (the "Software"), to deal
+//  in the Software without restriction, including without limitation the rights
+//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+//  copies of the Software, and to permit persons to whom the Software is
+//  furnished to do so, subject to the following conditions:
+//
+//  The above copyright notice and this permission notice shall be included in
+//  all copies or substantial portions of the Software.
+//
+//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+//  THE SOFTWARE.
+
+#if os(iOS) || os(tvOS)
+    import UIKit
+#else
+    import AppKit
+#endif
+
+
+public protocol LayoutConstraintItem: class {
+}
+
+extension ConstraintLayoutGuide : LayoutConstraintItem {
+}
+
+extension ConstraintView : LayoutConstraintItem {
+}
+
+
+extension LayoutConstraintItem {
+    
+    internal func prepare() {
+        if let view = self as? ConstraintView {
+            view.translatesAutoresizingMaskIntoConstraints = false
+        }
+    }
+    
+    internal var superview: ConstraintView? {
+        if let view = self as? ConstraintView {
+            return view.superview
+        }
+        
+        if #available(iOS 9.0, *), let guide = self as? ConstraintLayoutGuide {
+            return guide.owningView
+        }
+        
+        return nil
+    }
+    internal var constraints: [Constraint] {
+        return self.constraintsHashTable.allObjects
+    }
+    
+    internal func add(constraints: [Constraint]) {
+        let hashTable = self.constraintsHashTable
+        for constraint in constraints {
+            hashTable.add(constraint)
+        }
+    }
+    
+    internal func remove(constraints: [Constraint]) {
+        let hashTable = self.constraintsHashTable
+        for constraint in constraints {
+            hashTable.remove(constraint)
+        }
+    }
+    
+    private var constraintsHashTable: NSHashTable<Constraint> {
+        let constraints: NSHashTable<Constraint>
+        
+        if let existing = objc_getAssociatedObject(self, &constraintsKey) as? NSHashTable<Constraint> {
+            constraints = existing
+        } else {
+            constraints = NSHashTable<Constraint>()
+            objc_setAssociatedObject(self, &constraintsKey, constraints, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
+        }
+        return constraints
+        
+    }
+    
+}
+private var constraintsKey: UInt8 = 0