diff --git a/.gitignore b/.gitignore index c0dbc2e..79fa0df 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.build/ project.xcworkspace xcuserdata Examples/ diff --git a/Package.swift b/Package.swift index 2e87314..321d426 100644 --- a/Package.swift +++ b/Package.swift @@ -1,3 +1,4 @@ +// swift-tools-version:4.0 // // SnapKit // @@ -25,5 +26,12 @@ import PackageDescription let package = Package( - name: "SnapKit" + name: "SnapKit", + products: [ + .library(name: "SnapKit", targets: ["SnapKit"]), + ], + targets: [ + .target(name: "SnapKit", path: "Source"), + .testTarget(name: "SnapKitTests", dependencies: ["SnapKit"]), + ] ) diff --git a/SnapKit.xcodeproj/project.pbxproj b/SnapKit.xcodeproj/project.pbxproj index 58f9b93..b0193f2 100644 --- a/SnapKit.xcodeproj/project.pbxproj +++ b/SnapKit.xcodeproj/project.pbxproj @@ -82,8 +82,8 @@ EEBCC9E219CC627E0083B827 /* SnapKit Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "SnapKit Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; EECDB3641AC0C95C006BBC11 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; EECDB3661AC0C95C006BBC11 /* SnapKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SnapKit.h; sourceTree = ""; }; - EECDB3691AC0C95C006BBC11 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - EECDB36A1AC0C95C006BBC11 /* Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests.swift; sourceTree = ""; }; + EECDB3691AC0C95C006BBC11 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = SnapKitTests/Info.plist; sourceTree = ""; }; + EECDB36A1AC0C95C006BBC11 /* Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Tests.swift; path = SnapKitTests/Tests.swift; sourceTree = ""; }; EEF68F9D1D78492400980C26 /* ConstraintLayoutGuideDSL.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConstraintLayoutGuideDSL.swift; sourceTree = ""; }; EEF68FA51D784A5300980C26 /* ConstraintDSL.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConstraintDSL.swift; sourceTree = ""; }; EEF68FAF1D784FB100980C26 /* ConstraintLayoutGuide+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ConstraintLayoutGuide+Extensions.swift"; sourceTree = ""; }; @@ -559,7 +559,7 @@ buildSettings = { "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; DEVELOPMENT_TEAM = ""; - INFOPLIST_FILE = "$(SRCROOT)/Tests/Info.plist"; + INFOPLIST_FILE = "$(SRCROOT)/Tests/SnapKitTests/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks @loader_path/../Frameworks @executable_path/../Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "io.snapkit.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -572,7 +572,7 @@ buildSettings = { "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; DEVELOPMENT_TEAM = ""; - INFOPLIST_FILE = "$(SRCROOT)/Tests/Info.plist"; + INFOPLIST_FILE = "$(SRCROOT)/Tests/SnapKitTests/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks @loader_path/../Frameworks @executable_path/../Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "io.snapkit.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; diff --git a/Source/Constraint.swift b/Source/Constraint.swift index 2720745..6e4948e 100644 --- a/Source/Constraint.swift +++ b/Source/Constraint.swift @@ -49,12 +49,23 @@ public final class Constraint { public var layoutConstraints: [LayoutConstraint] public var isActive: Bool { - for layoutConstraint in self.layoutConstraints { - if layoutConstraint.isActive { - return true + set { + if newValue { + activate() + } + else { + deactivate() } } - return false + + get { + for layoutConstraint in self.layoutConstraints { + if layoutConstraint.isActive { + return true + } + } + return false + } } // MARK: Initialization @@ -214,6 +225,12 @@ public final class Constraint { return self } + @discardableResult + public func update(priority: ConstraintPriority) -> Constraint { + self.priority = priority.value + return self + } + @available(*, deprecated:3.0, message:"Use update(offset: ConstraintOffsetTarget) instead.") public func updateOffset(amount: ConstraintOffsetTarget) -> Void { self.update(offset: amount) } diff --git a/Source/ConstraintAttributes.swift b/Source/ConstraintAttributes.swift index 10bddb1..5e2367e 100644 --- a/Source/ConstraintAttributes.swift +++ b/Source/ConstraintAttributes.swift @@ -28,7 +28,9 @@ #endif -internal struct ConstraintAttributes : OptionSet { +internal struct ConstraintAttributes : OptionSet, ExpressibleByIntegerLiteral { + + typealias IntegerLiteralType = UInt internal init(rawValue: UInt) { self.rawValue = rawValue @@ -39,10 +41,13 @@ internal struct ConstraintAttributes : OptionSet { internal init(nilLiteral: ()) { self.rawValue = 0 } + internal init(integerLiteral rawValue: IntegerLiteralType) { + self.init(rawValue: rawValue) + } internal private(set) var rawValue: UInt - internal static var allZeros: ConstraintAttributes { return self.init(0) } - internal static func convertFromNilLiteral() -> ConstraintAttributes { return self.init(0) } + internal static var allZeros: ConstraintAttributes { return 0 } + internal static func convertFromNilLiteral() -> ConstraintAttributes { return 0 } internal var boolValue: Bool { return self.rawValue != 0 } internal func toRaw() -> UInt { return self.rawValue } @@ -51,57 +56,57 @@ 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 lastBaseline: ConstraintAttributes { return self.init(1024) } + internal static var none: ConstraintAttributes { return 0 } + internal static var left: ConstraintAttributes { return 1 } + internal static var top: ConstraintAttributes { return 2 } + internal static var right: ConstraintAttributes { return 4 } + internal static var bottom: ConstraintAttributes { return 8 } + internal static var leading: ConstraintAttributes { return 16 } + internal static var trailing: ConstraintAttributes { return 32 } + internal static var width: ConstraintAttributes { return 64 } + internal static var height: ConstraintAttributes { return 128 } + internal static var centerX: ConstraintAttributes { return 256 } + internal static var centerY: ConstraintAttributes { return 512 } + internal static var lastBaseline: ConstraintAttributes { return 1024 } @available(iOS 8.0, OSX 10.11, *) - internal static var firstBaseline: ConstraintAttributes { return self.init(2048) } + internal static var firstBaseline: ConstraintAttributes { return 2048 } @available(iOS 8.0, *) - internal static var leftMargin: ConstraintAttributes { return self.init(4096) } + internal static var leftMargin: ConstraintAttributes { return 4096 } @available(iOS 8.0, *) - internal static var rightMargin: ConstraintAttributes { return self.init(8192) } + internal static var rightMargin: ConstraintAttributes { return 8192 } @available(iOS 8.0, *) - internal static var topMargin: ConstraintAttributes { return self.init(16384) } + internal static var topMargin: ConstraintAttributes { return 16384 } @available(iOS 8.0, *) - internal static var bottomMargin: ConstraintAttributes { return self.init(32768) } + internal static var bottomMargin: ConstraintAttributes { return 32768 } @available(iOS 8.0, *) - internal static var leadingMargin: ConstraintAttributes { return self.init(65536) } + internal static var leadingMargin: ConstraintAttributes { return 65536 } @available(iOS 8.0, *) - internal static var trailingMargin: ConstraintAttributes { return self.init(131072) } + internal static var trailingMargin: ConstraintAttributes { return 131072 } @available(iOS 8.0, *) - internal static var centerXWithinMargins: ConstraintAttributes { return self.init(262144) } + internal static var centerXWithinMargins: ConstraintAttributes { return 262144 } @available(iOS 8.0, *) - internal static var centerYWithinMargins: ConstraintAttributes { return self.init(524288) } + internal static var centerYWithinMargins: ConstraintAttributes { return 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 15 } + internal static var size: ConstraintAttributes { return 192 } + internal static var center: ConstraintAttributes { return 768 } @available(iOS 8.0, *) - internal static var margins: ConstraintAttributes { return self.init(61440) } + internal static var margins: ConstraintAttributes { return 61440 } @available(iOS 8.0, *) - internal static var centerWithinMargins: ConstraintAttributes { return self.init(786432) } + internal static var centerWithinMargins: ConstraintAttributes { return 786432 } internal var layoutAttributes:[LayoutAttribute] { var attrs = [LayoutAttribute]() diff --git a/Source/ConstraintMaker.swift b/Source/ConstraintMaker.swift index b20cdb5..91f35f1 100644 --- a/Source/ConstraintMaker.swift +++ b/Source/ConstraintMaker.swift @@ -171,15 +171,7 @@ public class ConstraintMaker { } internal static func makeConstraints(item: LayoutConstraintItem, closure: (_ make: ConstraintMaker) -> Void) { - let maker = ConstraintMaker(item: item) - closure(maker) - var constraints: [Constraint] = [] - for description in maker.descriptions { - guard let constraint = description.constraint else { - continue - } - constraints.append(constraint) - } + let constraints = prepareConstraints(item: item, closure: closure) for constraint in constraints { constraint.activateIfNeeded(updatingExisting: false) } @@ -196,15 +188,7 @@ public class ConstraintMaker { return } - let maker = ConstraintMaker(item: item) - closure(maker) - var constraints: [Constraint] = [] - for description in maker.descriptions { - guard let constraint = description.constraint else { - continue - } - constraints.append(constraint) - } + let constraints = prepareConstraints(item: item, closure: closure) for constraint in constraints { constraint.activateIfNeeded(updatingExisting: true) } diff --git a/Source/ConstraintPriorityTarget.swift b/Source/ConstraintPriorityTarget.swift index eb32f79..064f750 100644 --- a/Source/ConstraintPriorityTarget.swift +++ b/Source/ConstraintPriorityTarget.swift @@ -73,3 +73,13 @@ extension CGFloat: ConstraintPriorityTarget { } } + +#if os(iOS) || os(tvOS) +extension UILayoutPriority: ConstraintPriorityTarget { + + public var constraintPriorityTargetValue: Float { + return self.rawValue + } + +} +#endif diff --git a/Source/Typealiases.swift b/Source/Typealiases.swift index 8a44151..ded96cc 100644 --- a/Source/Typealiases.swift +++ b/Source/Typealiases.swift @@ -25,8 +25,13 @@ import Foundation #if os(iOS) || os(tvOS) import UIKit +#if swift(>=4.2) + typealias LayoutRelation = NSLayoutConstraint.Relation + typealias LayoutAttribute = NSLayoutConstraint.Attribute +#else typealias LayoutRelation = NSLayoutRelation typealias LayoutAttribute = NSLayoutAttribute +#endif typealias LayoutPriority = UILayoutPriority #else import AppKit diff --git a/Tests/Info.plist b/Tests/SnapKitTests/Info.plist similarity index 100% rename from Tests/Info.plist rename to Tests/SnapKitTests/Info.plist diff --git a/Tests/Tests.swift b/Tests/SnapKitTests/Tests.swift similarity index 94% rename from Tests/Tests.swift rename to Tests/SnapKitTests/Tests.swift index db414ff..dd4a309 100644 --- a/Tests/Tests.swift +++ b/Tests/SnapKitTests/Tests.swift @@ -264,6 +264,40 @@ class SnapKitTests: XCTestCase { } + func testSetIsActivatedConstraints() { + 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?.isActive = true + c2?.isActive = false + + XCTAssertEqual(self.container.snp_constraints.count, 1, "Should have 1 constraint") + + c1?.isActive = true + c2?.isActive = true + + XCTAssertEqual(self.container.snp_constraints.count, 2, "Should have 2 constraints") + + c1?.isActive = false + c2?.isActive = false + + XCTAssertEqual(self.container.snp_constraints.count, 0, "Should have 0 constraints") + + } + func testEdgeConstraints() { let view = View() self.container.addSubview(view)