From a07ead5c8cb6c7b2972ea7bdcfe49f9e05d791e1 Mon Sep 17 00:00:00 2001 From: Peter Schumacher Date: Mon, 29 Aug 2016 16:09:15 +0200 Subject: [PATCH 1/2] added Support for UILayoutguide --- SnapKit.xcodeproj/project.pbxproj | 4 ++ Source/ConstraintDescription.swift | 19 +++++++ Source/ConstraintItem.swift | 7 +++ Source/LayoutGuide+SnapKit.swift | 91 ++++++++++++++++++++++++++++++ 4 files changed, 121 insertions(+) create mode 100644 Source/LayoutGuide+SnapKit.swift diff --git a/SnapKit.xcodeproj/project.pbxproj b/SnapKit.xcodeproj/project.pbxproj index afac868..b90b458 100644 --- a/SnapKit.xcodeproj/project.pbxproj +++ b/SnapKit.xcodeproj/project.pbxproj @@ -31,6 +31,7 @@ 56A0DC221C859F15005973AB /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56A0DC211C859F15005973AB /* AppDelegate.swift */; }; 56A0DC321C85A2C1005973AB /* BasicUIScrollViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56A0DC311C85A2C1005973AB /* BasicUIScrollViewController.swift */; }; 56A0DC341C85AFBF005973AB /* SimpleLayoutViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56A0DC331C85AFBF005973AB /* SimpleLayoutViewController.swift */; }; + 6BA7C9EA1D7472B3006586BC /* LayoutGuide+SnapKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BA7C9E91D7472B3006586BC /* LayoutGuide+SnapKit.swift */; }; EE4910981B19A26000A54F1F /* ViewController+SnapKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE4910971B19A26000A54F1F /* ViewController+SnapKit.swift */; }; EE4910991B19A40200A54F1F /* SnapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EEBCC9D819CC627D0083B827 /* SnapKit.framework */; }; EE94F6091AC0F10A008767FF /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EE94F6081AC0F10A008767FF /* UIKit.framework */; }; @@ -107,6 +108,7 @@ 56A0DC211C859F15005973AB /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 56A0DC311C85A2C1005973AB /* BasicUIScrollViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BasicUIScrollViewController.swift; sourceTree = ""; }; 56A0DC331C85AFBF005973AB /* SimpleLayoutViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SimpleLayoutViewController.swift; sourceTree = ""; }; + 6BA7C9E91D7472B3006586BC /* LayoutGuide+SnapKit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "LayoutGuide+SnapKit.swift"; sourceTree = ""; }; EE4910971B19A26000A54F1F /* ViewController+SnapKit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ViewController+SnapKit.swift"; sourceTree = ""; }; 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; }; @@ -251,6 +253,7 @@ isa = PBXGroup; children = ( EECDB3661AC0C95C006BBC11 /* SnapKit.h */, + 6BA7C9E91D7472B3006586BC /* LayoutGuide+SnapKit.swift */, EEFCF32E1AD926AE00A425FA /* SnapKit.swift */, EECDB35E1AC0C95C006BBC11 /* Constraint.swift */, EEFCF3311AD9432400A425FA /* ConstraintDescription.swift */, @@ -604,6 +607,7 @@ files = ( EECDB36C1AC0C9A6006BBC11 /* Constraint.swift in Sources */, EEFCF32F1AD926AE00A425FA /* SnapKit.swift in Sources */, + 6BA7C9EA1D7472B3006586BC /* LayoutGuide+SnapKit.swift in Sources */, EEFCF32C1AD910B900A425FA /* Debugging.swift in Sources */, EECDB3701AC0C9A6006BBC11 /* ConstraintRelation.swift in Sources */, EEFCF3321AD9432400A425FA /* ConstraintDescription.swift in Sources */, diff --git a/Source/ConstraintDescription.swift b/Source/ConstraintDescription.swift index 384ee30..2250ee9 100644 --- a/Source/ConstraintDescription.swift +++ b/Source/ConstraintDescription.swift @@ -95,6 +95,10 @@ public protocol ConstraintDescriptionRelatable: class { func equalTo(other: ConstraintItem) -> ConstraintDescriptionEditable func equalTo(other: View) -> ConstraintDescriptionEditable + #if os(iOS) || os(tvOS) + @available(iOS 9.0, *) + func equalTo(other: UILayoutGuide) -> ConstraintDescriptionEditable + #endif func equalToSuperview() -> ConstraintDescriptionEditable @available(iOS 7.0, *) func equalTo(other: LayoutSupport) -> ConstraintDescriptionEditable @@ -232,6 +236,14 @@ internal class ConstraintDescription: ConstraintDescriptionExtendable, Constrain internal func equalTo(other: View) -> ConstraintDescriptionEditable { return self.constrainTo(other, relation: .Equal) } + + #if os(iOS) || os(tvOS) + @available(iOS 9.0, *) + internal func equalTo(other: UILayoutGuide) -> ConstraintDescriptionEditable { + return self.constrainTo(other, relation: .Equal) + } + #endif + internal func equalToSuperview() -> ConstraintDescriptionEditable { guard let superview = fromItem.view?.superview else { fatalError("equalToSuperview() requires the view have a superview before being set.") @@ -598,6 +610,13 @@ internal class ConstraintDescription: ConstraintDescriptionExtendable, Constrain return constrainTo(ConstraintItem(object: other, attributes: ConstraintAttributes.None), relation: relation) } + #if os(iOS) || os(tvOS) + @available(iOS 9.0, *) + private func constrainTo(other: UILayoutGuide, relation: ConstraintRelation) -> ConstraintDescription { + return constrainTo(ConstraintItem(object: other, attributes: ConstraintAttributes.None), relation: relation) + } + #endif + @available(iOS 9.0, OSX 10.11, *) private func constrainTo(other: NSLayoutAnchor, relation: ConstraintRelation) -> ConstraintDescription { return constrainTo(ConstraintItem(object: other, attributes: ConstraintAttributes.None), relation: relation) diff --git a/Source/ConstraintItem.swift b/Source/ConstraintItem.swift index b2c9062..77629f7 100644 --- a/Source/ConstraintItem.swift +++ b/Source/ConstraintItem.swift @@ -48,6 +48,13 @@ public class ConstraintItem { internal var layoutSupport: LayoutSupport? { return self.object as? LayoutSupport } + + #if os(iOS) || os(tvOS) + @available(iOS 9.0, *) + internal var layoutguide: UILayoutGuide? { + return self.object as? UILayoutGuide + } + #endif } diff --git a/Source/LayoutGuide+SnapKit.swift b/Source/LayoutGuide+SnapKit.swift new file mode 100644 index 0000000..abbbbc1 --- /dev/null +++ b/Source/LayoutGuide+SnapKit.swift @@ -0,0 +1,91 @@ +// +// LayoutGuide+SnapKit.swift +// SnapKit +// +// Created by Schumacher Peter on 29/08/16. +// Copyright © 2016 SnapKit Team. All rights reserved. +// + +import UIKit + +/** + Used to expose public API on UILayoutGuide + */ +@available(iOS 9.0, *) +public extension UILayoutGuide { + /// left edge + public var snp_left: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.Left) } + + /// top edge + public var snp_top: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.Top) } + + /// right edge + public var snp_right: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.Right) } + + /// bottom edge + public var snp_bottom: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.Bottom) } + + /// leading edge + public var snp_leading: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.Leading) } + + /// trailing edge + public var snp_trailing: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.Trailing) } + + /// width dimension + public var snp_width: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.Width) } + + /// height dimension + public var snp_height: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.Height) } + + /// centerX position + public var snp_centerX: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.CenterX) } + + /// centerY position + public var snp_centerY: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.CenterY) } + + /// baseline position + public var snp_baseline: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.Baseline) } + + /// first baseline position + public var snp_firstBaseline: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.FirstBaseline) } + + /// left margin + public var snp_leftMargin: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.LeftMargin) } + + /// right margin + public var snp_rightMargin: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.RightMargin) } + + /// top margin + public var snp_topMargin: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.TopMargin) } + + /// bottom margin + public var snp_bottomMargin: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.BottomMargin) } + + /// leading margin + public var snp_leadingMargin: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.LeadingMargin) } + + /// trailing margin + public var snp_trailingMargin: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.TrailingMargin) } + + /// centerX within margins + public var snp_centerXWithinMargins: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.CenterXWithinMargins) } + + /// centerY within margins + public var snp_centerYWithinMargins: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.CenterYWithinMargins) } + + // top + left + bottom + right edges + public var snp_edges: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.Edges) } + + // width + height dimensions + public var snp_size: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.Size) } + + // centerX + centerY positions + public var snp_center: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.Center) } + + // top + left + bottom + right margins + public var snp_margins: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.Margins) } + + // centerX + centerY within margins + public var snp_centerWithinMargins: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.CenterWithinMargins) } + +} From d995bd134e33a9814ac1e4e1b84d0ac47068fad7 Mon Sep 17 00:00:00 2001 From: Peter Schumacher Date: Tue, 30 Aug 2016 09:08:37 +0200 Subject: [PATCH 2/2] added a Test --- Tests/Tests.swift | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Tests/Tests.swift b/Tests/Tests.swift index d317194..a368388 100644 --- a/Tests/Tests.swift +++ b/Tests/Tests.swift @@ -29,6 +29,24 @@ class SnapKitTests: XCTestCase { super.tearDown() } + @available(iOS 9.0, *) + func testReadableLayoutGuide() { + #if os(iOS) || os(tvOS) + let view = UIView(frame: CGRectMake(0, 0, 300, 300)) + + view.addSubview(self.container) + + let guide = view.readableContentGuide + + self.container.snp_makeConstraints { (make) -> Void in + make.top.equalTo(guide) + make.bottom.equalTo(guide) + } + print(view.snp_constraints) + XCTAssertEqual(view.snp_constraints.count, 12, "Should have 12 constraints installed") + #endif + } + func testLayoutGuideConstraints() { #if os(iOS) || os(tvOS) let vc = UIViewController()