From a07ef8b04c65faacc74974b38b396b52e001a735 Mon Sep 17 00:00:00 2001 From: Benjamin Chrobot Date: Fri, 13 Oct 2017 05:32:30 -0400 Subject: [PATCH 1/6] Add support for UILayoutPriority as priority target. (#466) * Add support for UILayoutPriority as priority target. * Fixed for tvOS --- Source/ConstraintPriorityTarget.swift | 10 ++++++++++ 1 file changed, 10 insertions(+) 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 From 2c8262ef9f00a250aae4f5f3c2a9539eb1c39520 Mon Sep 17 00:00:00 2001 From: Benjamin Chrobot Date: Fri, 13 Oct 2017 05:33:36 -0400 Subject: [PATCH 2/6] Add update(priority: ConstraintPriority) method (#467) * Add update(priority: ConstraintPriority) method * Fix copy-paste error --- Source/Constraint.swift | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Source/Constraint.swift b/Source/Constraint.swift index 2720745..0509f61 100644 --- a/Source/Constraint.swift +++ b/Source/Constraint.swift @@ -214,6 +214,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) } From 01124b9f325dc48f72707b56781a82ad0b4174c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20Unneb=C3=A4ck?= Date: Sat, 19 May 2018 05:47:52 +0100 Subject: [PATCH 3/6] Add Swift Package Manager support (#501) --- .gitignore | 1 + Package.swift | 10 +++++++++- SnapKit.xcodeproj/project.pbxproj | 8 ++++---- Tests/{ => SnapKitTests}/Info.plist | 0 Tests/{ => SnapKitTests}/Tests.swift | 0 5 files changed, 14 insertions(+), 5 deletions(-) rename Tests/{ => SnapKitTests}/Info.plist (100%) rename Tests/{ => SnapKitTests}/Tests.swift (100%) 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/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 100% rename from Tests/Tests.swift rename to Tests/SnapKitTests/Tests.swift From 0503c24de8006fd6c94f91c74db09cda80af00c3 Mon Sep 17 00:00:00 2001 From: Mauro Vime Castillo Date: Mon, 11 Jun 2018 05:46:30 +0200 Subject: [PATCH 4/6] Swift4.2 (#516) --- Source/Typealiases.swift | 5 +++++ 1 file changed, 5 insertions(+) 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 From 163f5369d344ad2d8de2275c7aaab9ce6321cc3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?o=28=EF=BF=A3=E3=81=B8=EF=BF=A3=29o?= Date: Sat, 23 Jun 2018 19:14:50 +0800 Subject: [PATCH 5/6] make ConstraintAttributes conform to ExpressibleByIntegerLiteral (#520) --- Source/ConstraintAttributes.swift | 63 +++++++++++++++++-------------- 1 file changed, 34 insertions(+), 29 deletions(-) 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]() From 15beb5221834e220f099a87beb80cc9d9abb16cf Mon Sep 17 00:00:00 2001 From: "Colin T.A. Gray" Date: Sat, 23 Jun 2018 05:15:34 -0600 Subject: [PATCH 6/6] Adds 'constraint.isActive = bool' to Constraint (#496) * delegate identical 'constraint creation' code to 'prepareConstraints' * adds 'set(isActivated:)' method to call appropriate 'activate/deactivate' based on bool cleans up about 30 lines of if foo { activate } else { deactivate } code in my app * instead of 'set(isActivated:)', use 'isActive = value' --- Source/Constraint.swift | 19 +++++++++++++++---- Source/ConstraintMaker.swift | 20 ++------------------ Tests/SnapKitTests/Tests.swift | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 22 deletions(-) diff --git a/Source/Constraint.swift b/Source/Constraint.swift index 0509f61..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 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/Tests/SnapKitTests/Tests.swift b/Tests/SnapKitTests/Tests.swift index db414ff..dd4a309 100644 --- a/Tests/SnapKitTests/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)