From 2edb7b9ff3aaac8ffc61a958212adb450a9283ab Mon Sep 17 00:00:00 2001 From: Robert Payne Date: Wed, 30 Jul 2014 12:55:31 +1200 Subject: [PATCH] Added support for OS X * Added "Insets" class which makes EdgeInsets a typealias on iOS and a custom struct on OS X * Added OS checks and fixed API issues where necessary --- Snappy.xcodeproj/project.pbxproj | 4 +++ Snappy/Constraint.swift | 36 ++++++++++++++---------- Snappy/ConstraintMaker.swift | 12 ++++++++ Snappy/Insets.swift | 45 ++++++++++++++++++++++++++++++ Snappy/LayoutConstraint.swift | 4 +++ Snappy/View.swift | 8 ++++-- SnappyExample/ViewController.swift | 2 +- 7 files changed, 94 insertions(+), 17 deletions(-) create mode 100644 Snappy/Insets.swift diff --git a/Snappy.xcodeproj/project.pbxproj b/Snappy.xcodeproj/project.pbxproj index e8aa53d..6210427 100644 --- a/Snappy.xcodeproj/project.pbxproj +++ b/Snappy.xcodeproj/project.pbxproj @@ -14,6 +14,7 @@ DD03E3241981B72A00E0DE94 /* ConstraintMaker.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD03E3231981B72A00E0DE94 /* ConstraintMaker.swift */; }; DD03E32A1981B7BF00E0DE94 /* View.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD03E3291981B7BF00E0DE94 /* View.swift */; }; DDC9FDAE1981B4DD009612C7 /* SnappyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC9FDAD1981B4DD009612C7 /* SnappyTests.swift */; }; + EE1004CB198879AD006CC759 /* Insets.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE1004CA198879AD006CC759 /* Insets.swift */; }; EEC6EB4E1985370500C27B12 /* LayoutConstraint.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEC6EB4D1985370500C27B12 /* LayoutConstraint.swift */; }; /* End PBXBuildFile section */ @@ -52,6 +53,7 @@ DDC9FD951981B4DD009612C7 /* Snappy.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Snappy.app; sourceTree = BUILT_PRODUCTS_DIR; }; DDC9FDA71981B4DD009612C7 /* SnappyTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SnappyTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; DDC9FDAD1981B4DD009612C7 /* SnappyTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SnappyTests.swift; sourceTree = ""; }; + EE1004CA198879AD006CC759 /* Insets.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Insets.swift; sourceTree = ""; }; EEC6EB4D1985370500C27B12 /* LayoutConstraint.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LayoutConstraint.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -87,6 +89,7 @@ DD03E31A1981B62D00E0DE94 /* Snappy */ = { isa = PBXGroup; children = ( + EE1004CA198879AD006CC759 /* Insets.swift */, EEC6EB4D1985370500C27B12 /* LayoutConstraint.swift */, DD03E3211981B71C00E0DE94 /* Constraint.swift */, DD03E3231981B72A00E0DE94 /* ConstraintMaker.swift */, @@ -225,6 +228,7 @@ DD03E32A1981B7BF00E0DE94 /* View.swift in Sources */, DD03E3221981B71C00E0DE94 /* Constraint.swift in Sources */, EEC6EB4E1985370500C27B12 /* LayoutConstraint.swift in Sources */, + EE1004CB198879AD006CC759 /* Insets.swift in Sources */, DD03E3241981B72A00E0DE94 /* ConstraintMaker.swift in Sources */, DD03E3191981B52F00E0DE94 /* ViewController.swift in Sources */, DD03E3151981B52F00E0DE94 /* AppDelegate.swift in Sources */, diff --git a/Snappy/Constraint.swift b/Snappy/Constraint.swift index f54eec4..936c16e 100644 --- a/Snappy/Constraint.swift +++ b/Snappy/Constraint.swift @@ -22,7 +22,11 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +#if os(iOS) import UIKit +#else +import AppKit +#endif /** * ConstraintAttributes is an options set that maps to NSLayoutAttributes. @@ -182,7 +186,7 @@ class Constraint { func equalTo(other: CGPoint) -> Constraint { return constrainTo(other, relation: .Equal) } - func equalTo(other: UIEdgeInsets) -> Constraint { + func equalTo(other: EdgeInsets) -> Constraint { return constrainTo(other, relation: .Equal) } @@ -206,7 +210,7 @@ class Constraint { func lessThanOrEqualTo(other: CGPoint) -> Constraint { return constrainTo(other, relation: .LessThanOrEqualTo) } - func lessThanOrEqualTo(other: UIEdgeInsets) -> Constraint { + func lessThanOrEqualTo(other: EdgeInsets) -> Constraint { return constrainTo(other, relation: .LessThanOrEqualTo) } @@ -230,7 +234,7 @@ class Constraint { func greaterThanOrEqualTo(other: CGPoint) -> Constraint { return constrainTo(other, relation: .GreaterThanOrEqualTo) } - func greaterThanOrEqualTo(other: UIEdgeInsets) -> Constraint { + func greaterThanOrEqualTo(other: EdgeInsets) -> Constraint { return constrainTo(other, relation: .GreaterThanOrEqualTo) } @@ -279,14 +283,14 @@ class Constraint { self.offset = amount return self } - func offset(amount: UIEdgeInsets) -> Constraint { + func offset(amount: EdgeInsets) -> Constraint { self.offset = amount return self } // MARK: insets - func insets(amount: UIEdgeInsets) -> Constraint { + func insets(amount: EdgeInsets) -> Constraint { self.offset = amount return self } @@ -359,7 +363,11 @@ class Constraint { func uninstall() { if let view = self.installedOnView { + #if os(iOS) var installedConstraints = view.constraints() + #else + var installedConstraints = view.constraints + #endif var constraintsToRemove: Array = [] for installedConstraint in installedConstraints { if let layoutConstraint = installedConstraint as? LayoutConstraint { @@ -425,7 +433,7 @@ class Constraint { self.constant = other return constrainTo(ConstraintItem(view: nil, attributes: ConstraintAttributes.None), relation: relation) } - private func constrainTo(other: UIEdgeInsets, relation: ConstraintRelation) -> Constraint { + private func constrainTo(other: EdgeInsets, relation: ConstraintRelation) -> Constraint { self.constant = other return constrainTo(ConstraintItem(view: nil, attributes: ConstraintAttributes.None), relation: relation) } @@ -454,15 +462,15 @@ private extension NSLayoutAttribute { if let float = value as? Float { return CGFloat(float) } - // Int + // Int else if let int = value as? Int { return CGFloat(int) } - // CGFloat + // CGFloat else if let float = value as? CGFloat { return float } - // CGSize + // CGSize else if let size = value as? CGSize { if self == .Width { return size.width @@ -470,7 +478,7 @@ private extension NSLayoutAttribute { return size.height } } - // CGPoint + // CGPoint else if let point = value as? CGPoint { if self == .Left || self == .CenterX { return point.x @@ -482,8 +490,8 @@ private extension NSLayoutAttribute { return -point.y } } - // UIEdgeInsets - else if let insets = value as? UIEdgeInsets { + // EdgeInsets + else if let insets = value as? EdgeInsets { if self == .Left { return insets.left } else if self == .Top { @@ -531,8 +539,8 @@ private extension NSLayoutAttribute { return point.y } } - // UIEdgeInsets - else if let insets = value as? UIEdgeInsets { + // EdgeInsets + else if let insets = value as? EdgeInsets { if self == .Left { return insets.left } else if self == .Top { diff --git a/Snappy/ConstraintMaker.swift b/Snappy/ConstraintMaker.swift index 0e4a959..d9aa417 100644 --- a/Snappy/ConstraintMaker.swift +++ b/Snappy/ConstraintMaker.swift @@ -22,7 +22,11 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +#if os(iOS) import UIKit +#else +import AppKit +#endif /** * ConstraintMaker is the maker in snappy that gets all constraints kickstarted @@ -59,7 +63,11 @@ class ConstraintMaker { } internal class func makeConstraints(view: View, block: (make: ConstraintMaker) -> ()) { + #if os(iOS) view.setTranslatesAutoresizingMaskIntoConstraints(false) + #else + view.translatesAutoresizingMaskIntoConstraints = false + #endif let maker = ConstraintMaker(view: view) block(make: maker) @@ -71,7 +79,11 @@ class ConstraintMaker { } internal class func remakeConstraints(view: View, block: (make: ConstraintMaker) -> ()) { + #if os(iOS) view.setTranslatesAutoresizingMaskIntoConstraints(false) + #else + view.translatesAutoresizingMaskIntoConstraints = false + #endif let maker = ConstraintMaker(view: view) block(make: maker) diff --git a/Snappy/Insets.swift b/Snappy/Insets.swift new file mode 100644 index 0000000..0f43c98 --- /dev/null +++ b/Snappy/Insets.swift @@ -0,0 +1,45 @@ +// +// Insets.swift +// Snappy +// +// Copyright (c) 2011-2014 Masonry Team - https://github.com/Masonry +// +// 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) +import UIKit +typealias EdgeInsets = UIEdgeInsets +func EdgeInsetsMake(top: CGFloat, left: CGFloat, bottom: CGFloat, right: CGFloat) -> EdgeInsets { + return EdgeInsets(top: top, left: left, bottom: bottom, right: right) +} +let EdgeInsetsZero = EdgeInsets(top: 0, left: 0, bottom: 0, right: 0) +#else +import AppKit +struct EdgeInsets { + var top: CGFloat // specify amount to inset (positive) for each of the edges. values can be negative to 'outset' + var left: CGFloat + var bottom: CGFloat + var right: CGFloat +} +func EdgeInsetsMake(top: CGFloat, left: CGFloat, bottom: CGFloat, right: CGFloat) -> EdgeInsets { + return EdgeInsets(top: top, left: left, bottom: bottom, right: right) +} +let EdgeInsetsZero = EdgeInsets(top: 0, left: 0, bottom: 0, right: 0) +#endif diff --git a/Snappy/LayoutConstraint.swift b/Snappy/LayoutConstraint.swift index 936e250..43c7f80 100644 --- a/Snappy/LayoutConstraint.swift +++ b/Snappy/LayoutConstraint.swift @@ -22,7 +22,11 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +#if os(iOS) import UIKit +#else +import AppKit +#endif /** * LayoutConstraint is a subclass of NSLayoutConstraint to assist Snappy and also provide better debugging diff --git a/Snappy/View.swift b/Snappy/View.swift index 7ed61b9..8167f8b 100644 --- a/Snappy/View.swift +++ b/Snappy/View.swift @@ -22,9 +22,14 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +#if os(iOS) import UIKit - typealias View = UIView +#else +import AppKit +typealias View = NSView +#endif + extension View { #if SNP_SHORTHAND var left: ConstraintItem { return ConstraintItem(view: self, attributes: ConstraintAttributes.Left) } @@ -50,7 +55,6 @@ extension View { func remakeConstraints(block: (maker: ConstraintMaker) -> ()) { ConstraintMaker.remakeConstraints(self, block: block) } - #else var snp_left: ConstraintItem { return ConstraintItem(view: self, attributes: ConstraintAttributes.Left) } var snp_top: ConstraintItem { return ConstraintItem(view: self, attributes: ConstraintAttributes.Top) } diff --git a/SnappyExample/ViewController.swift b/SnappyExample/ViewController.swift index 1def895..4dc0ad5 100644 --- a/SnappyExample/ViewController.swift +++ b/SnappyExample/ViewController.swift @@ -33,7 +33,7 @@ class ViewController: UIViewController { view3.layer.borderWidth = 2 superview.addSubview(view3) - let padding = UIEdgeInsets(top: 15, left: 10, bottom: 15, right: 10) + let padding = EdgeInsets(top: 15, left: 10, bottom: 15, right: 10) view1.snp_makeConstraints { make in