diff --git a/SnapKit.xcodeproj/project.pbxproj b/SnapKit.xcodeproj/project.pbxproj index bd593d0b..8a58a57b 100644 --- a/SnapKit.xcodeproj/project.pbxproj +++ b/SnapKit.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ 2DBA080E1F1FAD66001CFED4 /* Typealiases.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DBA080D1F1FAD66001CFED4 /* Typealiases.swift */; }; + 37AC176121B76CE700974541 /* RawRepresentable+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37AC176021B76CE700974541 /* RawRepresentable+Extensions.swift */; }; EE235F5F1C5785BC00C08960 /* Debugging.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE235F5E1C5785BC00C08960 /* Debugging.swift */; }; EE235F6D1C5785C600C08960 /* Constraint.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE235F621C5785C600C08960 /* Constraint.swift */; }; EE235F701C5785C600C08960 /* ConstraintDescription.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE235F631C5785C600C08960 /* ConstraintDescription.swift */; }; @@ -48,6 +49,7 @@ /* Begin PBXFileReference section */ 2DBA080D1F1FAD66001CFED4 /* Typealiases.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Typealiases.swift; sourceTree = ""; }; + 37AC176021B76CE700974541 /* RawRepresentable+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RawRepresentable+Extensions.swift"; sourceTree = ""; }; 537DCE9A1C35CD4100B5B899 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS9.1.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; EE235F5E1C5785BC00C08960 /* Debugging.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Debugging.swift; sourceTree = ""; }; EE235F621C5785C600C08960 /* Constraint.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Constraint.swift; sourceTree = ""; }; @@ -134,6 +136,7 @@ children = ( EE235FC61C5785E200C08960 /* ConstraintView+Extensions.swift */, EEF68FAF1D784FB100980C26 /* ConstraintLayoutGuide+Extensions.swift */, + 37AC176021B76CE700974541 /* RawRepresentable+Extensions.swift */, EEF68FB31D784FBA00980C26 /* UILayoutSupport+Extensions.swift */, ); name = Extensions; @@ -379,6 +382,7 @@ EE235F881C5785C600C08960 /* ConstraintItem.swift in Sources */, 2DBA080E1F1FAD66001CFED4 /* Typealiases.swift in Sources */, EE235F9A1C5785CE00C08960 /* ConstraintPriorityTarget.swift in Sources */, + 37AC176121B76CE700974541 /* RawRepresentable+Extensions.swift in Sources */, EEF68FC01D7865AA00980C26 /* ConstraintLayoutSupport.swift in Sources */, EEF68FB01D784FB100980C26 /* ConstraintLayoutGuide+Extensions.swift in Sources */, EE235F761C5785C600C08960 /* ConstraintConfig.swift in Sources */, diff --git a/Source/ConstraintConstantTarget.swift b/Source/ConstraintConstantTarget.swift index 24052ae6..b04676bb 100644 --- a/Source/ConstraintConstantTarget.swift +++ b/Source/ConstraintConstantTarget.swift @@ -29,6 +29,9 @@ public protocol ConstraintConstantTarget { + + func constraintConstantTargetValueFor(layoutAttribute: LayoutAttribute) -> CGFloat + } extension CGPoint: ConstraintConstantTarget { @@ -42,7 +45,7 @@ extension ConstraintInsets: ConstraintConstantTarget { extension ConstraintConstantTarget { - internal func constraintConstantTargetValueFor(layoutAttribute: LayoutAttribute) -> CGFloat { + public func constraintConstantTargetValueFor(layoutAttribute: LayoutAttribute) -> CGFloat { if let value = self as? CGFloat { return value } diff --git a/Source/ConstraintInsetTarget.swift b/Source/ConstraintInsetTarget.swift index ba8a0f3e..effff0c6 100644 --- a/Source/ConstraintInsetTarget.swift +++ b/Source/ConstraintInsetTarget.swift @@ -29,6 +29,9 @@ public protocol ConstraintInsetTarget: ConstraintConstantTarget { + + var constraintInsetTargetValue: ConstraintInsets { get } + } extension Int: ConstraintInsetTarget { @@ -51,7 +54,7 @@ extension ConstraintInsets: ConstraintInsetTarget { extension ConstraintInsetTarget { - internal var constraintInsetTargetValue: ConstraintInsets { + public var constraintInsetTargetValue: ConstraintInsets { if let amount = self as? ConstraintInsets { return amount } else if let amount = self as? Float { diff --git a/Source/ConstraintOffsetTarget.swift b/Source/ConstraintOffsetTarget.swift index bd9e0a1e..47640835 100644 --- a/Source/ConstraintOffsetTarget.swift +++ b/Source/ConstraintOffsetTarget.swift @@ -29,6 +29,9 @@ public protocol ConstraintOffsetTarget: ConstraintConstantTarget { + + var constraintOffsetTargetValue: CGFloat { get } + } extension Int: ConstraintOffsetTarget { @@ -48,7 +51,7 @@ extension CGFloat: ConstraintOffsetTarget { extension ConstraintOffsetTarget { - internal var constraintOffsetTargetValue: CGFloat { + public var constraintOffsetTargetValue: CGFloat { let offset: CGFloat if let amount = self as? Float { offset = CGFloat(amount) diff --git a/Source/RawRepresentable+Extensions.swift b/Source/RawRepresentable+Extensions.swift new file mode 100644 index 00000000..c7953868 --- /dev/null +++ b/Source/RawRepresentable+Extensions.swift @@ -0,0 +1,61 @@ +// +// 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 extension RawRepresentable where Self: ConstraintConstantTarget, Self.RawValue: ConstraintConstantTarget { + + public func constraintConstantTargetValueFor(layoutAttribute: LayoutAttribute) -> CGFloat { + return rawValue.constraintConstantTargetValueFor(layoutAttribute: layoutAttribute) + } + +} + +public extension RawRepresentable where Self: ConstraintMultiplierTarget, Self.RawValue: ConstraintMultiplierTarget { + + public var constraintMultiplierTargetValue: CGFloat { + return rawValue.constraintMultiplierTargetValue + } + +} + +public extension RawRepresentable where Self: ConstraintOffsetTarget, Self.RawValue: ConstraintOffsetTarget { + + public var constraintOffsetTargetValue: CGFloat { + return rawValue.constraintOffsetTargetValue + } + +} + +public extension RawRepresentable where Self: ConstraintInsetTarget, Self.RawValue: ConstraintInsetTarget { + + public var constraintInsetTargetValue: ConstraintInsets { + return rawValue.constraintInsetTargetValue + } + +} diff --git a/Source/Typealiases.swift b/Source/Typealiases.swift index ded96ccd..63057acd 100644 --- a/Source/Typealiases.swift +++ b/Source/Typealiases.swift @@ -27,16 +27,16 @@ import Foundation import UIKit #if swift(>=4.2) typealias LayoutRelation = NSLayoutConstraint.Relation - typealias LayoutAttribute = NSLayoutConstraint.Attribute + public typealias LayoutAttribute = NSLayoutConstraint.Attribute #else typealias LayoutRelation = NSLayoutRelation - typealias LayoutAttribute = NSLayoutAttribute + public typealias LayoutAttribute = NSLayoutAttribute #endif typealias LayoutPriority = UILayoutPriority #else import AppKit typealias LayoutRelation = NSLayoutConstraint.Relation - typealias LayoutAttribute = NSLayoutConstraint.Attribute + public typealias LayoutAttribute = NSLayoutConstraint.Attribute typealias LayoutPriority = NSLayoutConstraint.Priority #endif diff --git a/Tests/SnapKitTests/Tests.swift b/Tests/SnapKitTests/Tests.swift index a4b587f7..d9a583f5 100644 --- a/Tests/SnapKitTests/Tests.swift +++ b/Tests/SnapKitTests/Tests.swift @@ -580,4 +580,29 @@ class SnapKitTests: XCTestCase { let higherPriority: ConstraintPriority = ConstraintPriority.high.advanced(by: 1) XCTAssertEqual(higherPriority.value, highPriority.value + 1) } + + func testEnumAsConstraints() { + let view = View() + self.container.addSubview(view) + + view.snp.makeConstraints { make in + make.top.equalTo(Enum.value) + make.height.equalToSuperview().multipliedBy(Enum.value) + make.left.equalToSuperview().offset(Enum.value) + make.right.equalToSuperview().inset(Enum.value) + } + + XCTAssertEqual(self.container.snp_constraints.count, 4, "Should have 4 constraints") + + let constraints = (self.container.snp_constraints as! [NSLayoutConstraint]).sorted { $0.constant > $1.constant } + + XCTAssertEqual(constraints[0].constant, Enum.value.rawValue, "Should be enum") + XCTAssertEqual(constraints[1].constant, Enum.value.rawValue, "Should be enum") + XCTAssertEqual(constraints[2].multiplier, Enum.value.rawValue, "Multiplier should be enum") + XCTAssertEqual(constraints[3].constant, -Enum.value.rawValue, "Should be negative enum") + } +} + +private enum Enum: CGFloat, ConstraintRelatableTarget, ConstraintMultiplierTarget, ConstraintOffsetTarget, ConstraintInsetTarget { + case value = 50 }