diff --git a/.travis.yml b/.travis.yml index 2309b3a..294eb13 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,15 +1,10 @@ language: objective-c -osx_image: xcode7.3 -branches: - only: - - master - - develop +osx_image: xcode8 + env: - - LC_CTYPE=en_US.UTF-8 LANG=en_US.UTF-8 -before_install: - - gem install xcpretty -N + - ACTION=test PLATFORM=Mac DESTINATION='platform=OS X' + - ACTION=test PLATFORM=iOS DESTINATION='platform=iOS Simulator,name=iPhone 6S' + - ACTION=test PLATFORM=tvOS DESTINATION='platform=tvOS Simulator,name=Apple TV 1080p' + script: - - set -o pipefail - - xcodebuild -project SnapKit.xcodeproj -scheme "SnapKit iOS" -sdk iphonesimulator -destination "platform=iOS Simulator,name=iPhone 6" ONLY_ACTIVE_ARCH=NO test | xcpretty -c - - xcodebuild -project SnapKit.xcodeproj -scheme "SnapKit OSX" ONLY_ACTIVE_ARCH=YES test | xcpretty -c - - pod lib lint --quick + - set -o pipefail && xcodebuild -scheme SnapKit -destination "$DESTINATION" $ACTION | xcpretty diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b5df91..10a7d99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,32 @@ CHANGELOG ======= +# 0.40.0.beta - WIP + +**SnapKit 0.40.0** is a complete re-write to take advantage of modern Swift 3.0 as well as +clean up the API. As such please use with caution and check your apps thoroughly + +### Breaking + +* iOS 7.0 support has been removed +* `install` and `uninstall` have been removed, use `activate` and `deactivate` instead +* DSL is now accessed through `.snp.*` rather than `.snp_*`. For example `view.snp.makeConstraints { }` +* Constraints are now updated through `update(offset:)`, `update(inset:)` and `update(priority:)` +* `.inset()` will no longer take `CGPoint` or `CGSize` as input +* `.offset()` will no longer take `CGPoint`, `CGSize`, `EdgeInsets` as input +* `updateConstraints` will no longer allow creating new constraints unless there are no existing constraints for the view. If it does generate new constraints it will throw a fatal error. +* `UIEdgeInsets` are now have their right and bottom value inverted for more natural results such as `make.edges.equalTo(UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)).inset()` + +### Enhancements + +* Debugging output has been improved to show exact file/line number from which the broken constraint was created +* Exceptions thrown during constraint creation have been replaced with `fatalError` with better output +* Constraints are now installed through `NSLayoutConstraint.activate` and what view they are added to is now deferred to UIKit +* Added `var contentHuggingPriority: CGFloat` to `make` +* Added `var contentCompressionResistancePriority: CGFloat` to `make` +* Added support for `UILayoutGuide` via `make.left.equalTo(guide.snp.top)` +* Added support for constraining edges to margins or vice versa via `make.edges.equalTo(other.snp.margins)` + # 0.22.0 - August 8 2016 * Added `layoutConstraint` getter to `Constraint` to get the underlying NSLayoutConstraints created by a constraint diff --git a/README.md b/README.md index 2b02d3b..04c8903 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ class MyViewController: UIViewController { super.viewDidLoad() self.view.addSubview(box) - box.snp_makeConstraints { make in + box.snp.makeConstraints { (make) -> Void in make.width.height.equalTo(50) make.center.equalTo(self.view) } @@ -30,7 +30,6 @@ class MyViewController: UIViewController { * [Documentation](http://snapkit.io/docs/) * [F.A.Q.](http://snapkit.io/faq/) -* [Legacy Platforms (iOS 7.0, OS X 10.9)](http://snapkit.io/legacy-platforms/) ## License diff --git a/SnapKit.podspec b/SnapKit.podspec index 16a2203..3fe34ce 100644 --- a/SnapKit.podspec +++ b/SnapKit.podspec @@ -1,12 +1,12 @@ Pod::Spec.new do |s| s.name = 'SnapKit' - s.version = '0.22.0' + s.version = '0.40.0.beta4' s.license = 'MIT' s.summary = 'Harness the power of auto layout with a simplified, chainable, and compile time safe syntax.' s.homepage = 'https://github.com/SnapKit/SnapKit' s.authors = { 'Robert Payne' => 'robertpayne@me.com' } s.social_media_url = 'http://twitter.com/robertjpayne' - s.source = { :git => 'https://github.com/SnapKit/SnapKit.git', :tag => '0.22.0' } + s.source = { :git => 'https://github.com/SnapKit/SnapKit.git', :tag => '0.40.0.beta4' } s.ios.deployment_target = '8.0' s.osx.deployment_target = '10.10' diff --git a/SnapKit.xcodeproj/project.pbxproj b/SnapKit.xcodeproj/project.pbxproj index afac868..e7480f6 100644 --- a/SnapKit.xcodeproj/project.pbxproj +++ b/SnapKit.xcodeproj/project.pbxproj @@ -7,163 +7,86 @@ objects = { /* Begin PBXBuildFile section */ - 537DCE9B1C35CD4100B5B899 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 537DCE9A1C35CD4100B5B899 /* UIKit.framework */; }; - 537DCE9C1C35CD9A00B5B899 /* Constraint.swift in Sources */ = {isa = PBXBuildFile; fileRef = EECDB35E1AC0C95C006BBC11 /* Constraint.swift */; }; - 537DCE9D1C35CDA300B5B899 /* SnapKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEFCF32E1AD926AE00A425FA /* SnapKit.swift */; }; - 537DCE9E1C35CDAA00B5B899 /* Debugging.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEFCF32B1AD910B900A425FA /* Debugging.swift */; }; - 537DCE9F1C35CDB700B5B899 /* ConstraintItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = EECDB3601AC0C95C006BBC11 /* ConstraintItem.swift */; }; - 537DCEA01C35CDF800B5B899 /* SnapKit.h in Headers */ = {isa = PBXBuildFile; fileRef = EECDB3661AC0C95C006BBC11 /* SnapKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 537DCEA11C35CE0000B5B899 /* ConstraintDescription.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEFCF3311AD9432400A425FA /* ConstraintDescription.swift */; }; - 537DCEA21C35CE0500B5B899 /* ConstraintMaker.swift in Sources */ = {isa = PBXBuildFile; fileRef = EECDB3611AC0C95C006BBC11 /* ConstraintMaker.swift */; }; - 537DCEA31C35CE0900B5B899 /* View+SnapKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = EECDB3671AC0C95C006BBC11 /* View+SnapKit.swift */; }; - 537DCEA41C35CE1500B5B899 /* ViewController+SnapKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE4910971B19A26000A54F1F /* ViewController+SnapKit.swift */; }; - 537DCEA51C35CE1B00B5B899 /* EdgeInsets.swift in Sources */ = {isa = PBXBuildFile; fileRef = EECDB3631AC0C95C006BBC11 /* EdgeInsets.swift */; }; - 537DCEA61C35CE2000B5B899 /* LayoutConstraint.swift in Sources */ = {isa = PBXBuildFile; fileRef = EECDB3651AC0C95C006BBC11 /* LayoutConstraint.swift */; }; - 537DCEA81C35CE3800B5B899 /* ConstraintRelation.swift in Sources */ = {isa = PBXBuildFile; fileRef = EECDB3621AC0C95C006BBC11 /* ConstraintRelation.swift */; }; - 537DCEA91C35CE3E00B5B899 /* ConstraintAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = EECDB35F1AC0C95C006BBC11 /* ConstraintAttributes.swift */; }; - 537DCEB41C35D90A00B5B899 /* SnapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 537DCE921C35CC8800B5B899 /* SnapKit.framework */; }; - 537DCEBA1C35DA9700B5B899 /* Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EECDB36A1AC0C95C006BBC11 /* Tests.swift */; }; - 56A0DC0E1C859E30005973AB /* ListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56A0DC0D1C859E30005973AB /* ListViewController.swift */; }; - 56A0DC131C859E30005973AB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 56A0DC121C859E30005973AB /* Assets.xcassets */; }; - 56A0DC161C859E30005973AB /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 56A0DC141C859E30005973AB /* LaunchScreen.storyboard */; }; - 56A0DC1C1C859E9A005973AB /* SnapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EEBCC9D819CC627D0083B827 /* SnapKit.framework */; }; - 56A0DC1D1C859E9A005973AB /* SnapKit.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = EEBCC9D819CC627D0083B827 /* SnapKit.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 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 */; }; - EE4910981B19A26000A54F1F /* ViewController+SnapKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE4910971B19A26000A54F1F /* ViewController+SnapKit.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 */; }; + EE235F731C5785C600C08960 /* ConstraintInsets.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE235F641C5785C600C08960 /* ConstraintInsets.swift */; }; + EE235F761C5785C600C08960 /* ConstraintConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE235F651C5785C600C08960 /* ConstraintConfig.swift */; }; + EE235F791C5785C600C08960 /* ConstraintView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE235F661C5785C600C08960 /* ConstraintView.swift */; }; + EE235F7F1C5785C600C08960 /* ConstraintRelation.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE235F681C5785C600C08960 /* ConstraintRelation.swift */; }; + EE235F851C5785C600C08960 /* ConstraintAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE235F6A1C5785C600C08960 /* ConstraintAttributes.swift */; }; + EE235F881C5785C600C08960 /* ConstraintItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE235F6B1C5785C600C08960 /* ConstraintItem.swift */; }; + EE235F8B1C5785C600C08960 /* LayoutConstraint.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE235F6C1C5785C600C08960 /* LayoutConstraint.swift */; }; + EE235F941C5785CE00C08960 /* ConstraintRelatableTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE235F8E1C5785CE00C08960 /* ConstraintRelatableTarget.swift */; }; + EE235F971C5785CE00C08960 /* ConstraintConstantTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE235F8F1C5785CE00C08960 /* ConstraintConstantTarget.swift */; }; + EE235F9A1C5785CE00C08960 /* ConstraintPriorityTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE235F901C5785CE00C08960 /* ConstraintPriorityTarget.swift */; }; + EE235F9D1C5785CE00C08960 /* ConstraintMultiplierTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE235F911C5785CE00C08960 /* ConstraintMultiplierTarget.swift */; }; + EE235FA01C5785CE00C08960 /* ConstraintOffsetTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE235F921C5785CE00C08960 /* ConstraintOffsetTarget.swift */; }; + EE235FA31C5785CE00C08960 /* ConstraintInsetTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE235F931C5785CE00C08960 /* ConstraintInsetTarget.swift */; }; + EE235FAC1C5785D400C08960 /* ConstraintMaker.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE235FA61C5785D400C08960 /* ConstraintMaker.swift */; }; + EE235FAF1C5785D400C08960 /* ConstraintMakerFinalizable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE235FA71C5785D400C08960 /* ConstraintMakerFinalizable.swift */; }; + EE235FB21C5785D400C08960 /* ConstraintMakerPriortizable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE235FA81C5785D400C08960 /* ConstraintMakerPriortizable.swift */; }; + EE235FB51C5785D400C08960 /* ConstraintMakerEditable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE235FA91C5785D400C08960 /* ConstraintMakerEditable.swift */; }; + EE235FB81C5785D400C08960 /* ConstraintMakerRelatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE235FAA1C5785D400C08960 /* ConstraintMakerRelatable.swift */; }; + EE235FBB1C5785D400C08960 /* ConstraintMakerExtendable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE235FAB1C5785D400C08960 /* ConstraintMakerExtendable.swift */; }; + EE235FC01C5785DC00C08960 /* ConstraintViewDSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE235FBE1C5785DC00C08960 /* ConstraintViewDSL.swift */; }; + EE235FC31C5785DC00C08960 /* ConstraintLayoutSupportDSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE235FBF1C5785DC00C08960 /* ConstraintLayoutSupportDSL.swift */; }; + EE235FC81C5785E200C08960 /* ConstraintView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE235FC61C5785E200C08960 /* ConstraintView+Extensions.swift */; }; EE4910991B19A40200A54F1F /* SnapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EEBCC9D819CC627D0083B827 /* SnapKit.framework */; }; - EE94F6091AC0F10A008767FF /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EE94F6081AC0F10A008767FF /* UIKit.framework */; }; - EE94F60B1AC0F10F008767FF /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EE94F60A1AC0F10F008767FF /* AppKit.framework */; }; - EE94F6111AC0F146008767FF /* SnapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EECDB37A1AC0C9D4006BBC11 /* SnapKit.framework */; }; - EECDB36C1AC0C9A6006BBC11 /* Constraint.swift in Sources */ = {isa = PBXBuildFile; fileRef = EECDB35E1AC0C95C006BBC11 /* Constraint.swift */; }; - EECDB36D1AC0C9A6006BBC11 /* ConstraintAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = EECDB35F1AC0C95C006BBC11 /* ConstraintAttributes.swift */; }; - EECDB36E1AC0C9A6006BBC11 /* ConstraintItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = EECDB3601AC0C95C006BBC11 /* ConstraintItem.swift */; }; - EECDB36F1AC0C9A6006BBC11 /* ConstraintMaker.swift in Sources */ = {isa = PBXBuildFile; fileRef = EECDB3611AC0C95C006BBC11 /* ConstraintMaker.swift */; }; - EECDB3701AC0C9A6006BBC11 /* ConstraintRelation.swift in Sources */ = {isa = PBXBuildFile; fileRef = EECDB3621AC0C95C006BBC11 /* ConstraintRelation.swift */; }; - EECDB3711AC0C9A6006BBC11 /* EdgeInsets.swift in Sources */ = {isa = PBXBuildFile; fileRef = EECDB3631AC0C95C006BBC11 /* EdgeInsets.swift */; }; - EECDB3721AC0C9A6006BBC11 /* LayoutConstraint.swift in Sources */ = {isa = PBXBuildFile; fileRef = EECDB3651AC0C95C006BBC11 /* LayoutConstraint.swift */; }; - EECDB3731AC0C9A6006BBC11 /* View+SnapKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = EECDB3671AC0C95C006BBC11 /* View+SnapKit.swift */; }; EECDB3741AC0C9B6006BBC11 /* SnapKit.h in Headers */ = {isa = PBXBuildFile; fileRef = EECDB3661AC0C95C006BBC11 /* SnapKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; EECDB3931AC0CB52006BBC11 /* Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EECDB36A1AC0C95C006BBC11 /* Tests.swift */; }; - EECDB3941AC0CB52006BBC11 /* Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EECDB36A1AC0C95C006BBC11 /* Tests.swift */; }; - EECDB3951AC0CBFF006BBC11 /* Constraint.swift in Sources */ = {isa = PBXBuildFile; fileRef = EECDB35E1AC0C95C006BBC11 /* Constraint.swift */; }; - EECDB3961AC0CBFF006BBC11 /* ConstraintAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = EECDB35F1AC0C95C006BBC11 /* ConstraintAttributes.swift */; }; - EECDB3971AC0CBFF006BBC11 /* ConstraintItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = EECDB3601AC0C95C006BBC11 /* ConstraintItem.swift */; }; - EECDB3981AC0CBFF006BBC11 /* ConstraintMaker.swift in Sources */ = {isa = PBXBuildFile; fileRef = EECDB3611AC0C95C006BBC11 /* ConstraintMaker.swift */; }; - EECDB3991AC0CBFF006BBC11 /* ConstraintRelation.swift in Sources */ = {isa = PBXBuildFile; fileRef = EECDB3621AC0C95C006BBC11 /* ConstraintRelation.swift */; }; - EECDB39A1AC0CBFF006BBC11 /* EdgeInsets.swift in Sources */ = {isa = PBXBuildFile; fileRef = EECDB3631AC0C95C006BBC11 /* EdgeInsets.swift */; }; - EECDB39B1AC0CBFF006BBC11 /* LayoutConstraint.swift in Sources */ = {isa = PBXBuildFile; fileRef = EECDB3651AC0C95C006BBC11 /* LayoutConstraint.swift */; }; - EECDB39C1AC0CBFF006BBC11 /* View+SnapKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = EECDB3671AC0C95C006BBC11 /* View+SnapKit.swift */; }; - EECDB39D1AC0CC03006BBC11 /* SnapKit.h in Headers */ = {isa = PBXBuildFile; fileRef = EECDB3661AC0C95C006BBC11 /* SnapKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; - EEFCF32C1AD910B900A425FA /* Debugging.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEFCF32B1AD910B900A425FA /* Debugging.swift */; }; - EEFCF32D1AD9250C00A425FA /* Debugging.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEFCF32B1AD910B900A425FA /* Debugging.swift */; }; - EEFCF32F1AD926AE00A425FA /* SnapKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEFCF32E1AD926AE00A425FA /* SnapKit.swift */; }; - EEFCF3301AD92C2200A425FA /* SnapKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEFCF32E1AD926AE00A425FA /* SnapKit.swift */; }; - EEFCF3321AD9432400A425FA /* ConstraintDescription.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEFCF3311AD9432400A425FA /* ConstraintDescription.swift */; }; - EEFCF3331AD9432400A425FA /* ConstraintDescription.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEFCF3311AD9432400A425FA /* ConstraintDescription.swift */; }; + EEF68F9E1D78492400980C26 /* ConstraintLayoutGuideDSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEF68F9D1D78492400980C26 /* ConstraintLayoutGuideDSL.swift */; }; + EEF68FA61D784A5300980C26 /* ConstraintDSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEF68FA51D784A5300980C26 /* ConstraintDSL.swift */; }; + EEF68FB01D784FB100980C26 /* UILayoutGuide+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEF68FAF1D784FB100980C26 /* UILayoutGuide+Extensions.swift */; }; + EEF68FB41D784FBA00980C26 /* UILayoutSupport+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEF68FB31D784FBA00980C26 /* UILayoutSupport+Extensions.swift */; }; + EEF68FBC1D78653000980C26 /* ConstraintLayoutGuide.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEF68FBB1D78653000980C26 /* ConstraintLayoutGuide.swift */; }; + EEF68FC01D7865AA00980C26 /* ConstraintLayoutSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEF68FBF1D7865AA00980C26 /* ConstraintLayoutSupport.swift */; }; /* End PBXBuildFile section */ -/* Begin PBXContainerItemProxy section */ - 56A0DC1E1C859E9A005973AB /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = DDC9FD8D1981B4DD009612C7 /* Project object */; - proxyType = 1; - remoteGlobalIDString = EEBCC9D719CC627D0083B827; - remoteInfo = "SnapKit iOS"; - }; - EECDB3861AC0C9D4006BBC11 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = DDC9FD8D1981B4DD009612C7 /* Project object */; - proxyType = 1; - remoteGlobalIDString = EECDB3791AC0C9D4006BBC11; - remoteInfo = "SnapKit OSX"; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 56A0DC201C859E9A005973AB /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - 56A0DC1D1C859E9A005973AB /* SnapKit.framework in Embed Frameworks */, - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - /* Begin PBXFileReference section */ - 537DCE921C35CC8800B5B899 /* SnapKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SnapKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 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; }; - 537DCEAF1C35D90A00B5B899 /* SnapKit tvOS Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "SnapKit tvOS Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; - 56A0DC091C859E30005973AB /* Example-iOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Example-iOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; - 56A0DC0D1C859E30005973AB /* ListViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListViewController.swift; sourceTree = ""; }; - 56A0DC121C859E30005973AB /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 56A0DC151C859E30005973AB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; - 56A0DC171C859E30005973AB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 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 = ""; }; - EE4910971B19A26000A54F1F /* ViewController+SnapKit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ViewController+SnapKit.swift"; sourceTree = ""; }; + 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 = ""; }; + EE235F631C5785C600C08960 /* ConstraintDescription.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConstraintDescription.swift; sourceTree = ""; }; + EE235F641C5785C600C08960 /* ConstraintInsets.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConstraintInsets.swift; sourceTree = ""; }; + EE235F651C5785C600C08960 /* ConstraintConfig.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConstraintConfig.swift; sourceTree = ""; }; + EE235F661C5785C600C08960 /* ConstraintView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConstraintView.swift; sourceTree = ""; }; + EE235F681C5785C600C08960 /* ConstraintRelation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConstraintRelation.swift; sourceTree = ""; }; + EE235F6A1C5785C600C08960 /* ConstraintAttributes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConstraintAttributes.swift; sourceTree = ""; }; + EE235F6B1C5785C600C08960 /* ConstraintItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConstraintItem.swift; sourceTree = ""; }; + EE235F6C1C5785C600C08960 /* LayoutConstraint.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LayoutConstraint.swift; sourceTree = ""; }; + EE235F8E1C5785CE00C08960 /* ConstraintRelatableTarget.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConstraintRelatableTarget.swift; sourceTree = ""; }; + EE235F8F1C5785CE00C08960 /* ConstraintConstantTarget.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConstraintConstantTarget.swift; sourceTree = ""; }; + EE235F901C5785CE00C08960 /* ConstraintPriorityTarget.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConstraintPriorityTarget.swift; sourceTree = ""; }; + EE235F911C5785CE00C08960 /* ConstraintMultiplierTarget.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConstraintMultiplierTarget.swift; sourceTree = ""; }; + EE235F921C5785CE00C08960 /* ConstraintOffsetTarget.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConstraintOffsetTarget.swift; sourceTree = ""; }; + EE235F931C5785CE00C08960 /* ConstraintInsetTarget.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConstraintInsetTarget.swift; sourceTree = ""; }; + EE235FA61C5785D400C08960 /* ConstraintMaker.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConstraintMaker.swift; sourceTree = ""; }; + EE235FA71C5785D400C08960 /* ConstraintMakerFinalizable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConstraintMakerFinalizable.swift; sourceTree = ""; }; + EE235FA81C5785D400C08960 /* ConstraintMakerPriortizable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConstraintMakerPriortizable.swift; sourceTree = ""; }; + EE235FA91C5785D400C08960 /* ConstraintMakerEditable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConstraintMakerEditable.swift; sourceTree = ""; }; + EE235FAA1C5785D400C08960 /* ConstraintMakerRelatable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConstraintMakerRelatable.swift; sourceTree = ""; }; + EE235FAB1C5785D400C08960 /* ConstraintMakerExtendable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConstraintMakerExtendable.swift; sourceTree = ""; }; + EE235FBE1C5785DC00C08960 /* ConstraintViewDSL.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConstraintViewDSL.swift; sourceTree = ""; }; + EE235FBF1C5785DC00C08960 /* ConstraintLayoutSupportDSL.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConstraintLayoutSupportDSL.swift; sourceTree = ""; }; + EE235FC61C5785E200C08960 /* ConstraintView+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ConstraintView+Extensions.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; }; EEBCC9D819CC627D0083B827 /* SnapKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SnapKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - EEBCC9E219CC627E0083B827 /* SnapKit iOS Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "SnapKit iOS Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; - EECDB35E1AC0C95C006BBC11 /* Constraint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constraint.swift; sourceTree = ""; }; - EECDB35F1AC0C95C006BBC11 /* ConstraintAttributes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConstraintAttributes.swift; sourceTree = ""; }; - EECDB3601AC0C95C006BBC11 /* ConstraintItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConstraintItem.swift; sourceTree = ""; }; - EECDB3611AC0C95C006BBC11 /* ConstraintMaker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConstraintMaker.swift; sourceTree = ""; }; - EECDB3621AC0C95C006BBC11 /* ConstraintRelation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConstraintRelation.swift; sourceTree = ""; }; - EECDB3631AC0C95C006BBC11 /* EdgeInsets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EdgeInsets.swift; sourceTree = ""; }; + 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 = ""; }; - EECDB3651AC0C95C006BBC11 /* LayoutConstraint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LayoutConstraint.swift; sourceTree = ""; }; EECDB3661AC0C95C006BBC11 /* SnapKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SnapKit.h; sourceTree = ""; }; - EECDB3671AC0C95C006BBC11 /* View+SnapKit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+SnapKit.swift"; 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 = ""; }; - EECDB37A1AC0C9D4006BBC11 /* SnapKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SnapKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - EECDB3841AC0C9D4006BBC11 /* SnapKit OSX Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "SnapKit OSX Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; - EEFCF32B1AD910B900A425FA /* Debugging.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Debugging.swift; sourceTree = ""; }; - EEFCF32E1AD926AE00A425FA /* SnapKit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SnapKit.swift; sourceTree = ""; }; - EEFCF3311AD9432400A425FA /* ConstraintDescription.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConstraintDescription.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 /* UILayoutGuide+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UILayoutGuide+Extensions.swift"; sourceTree = ""; }; + EEF68FB31D784FBA00980C26 /* UILayoutSupport+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UILayoutSupport+Extensions.swift"; sourceTree = ""; }; + EEF68FBB1D78653000980C26 /* ConstraintLayoutGuide.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConstraintLayoutGuide.swift; sourceTree = ""; }; + EEF68FBF1D7865AA00980C26 /* ConstraintLayoutSupport.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConstraintLayoutSupport.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - 537DCE8E1C35CC8800B5B899 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 537DCE9B1C35CD4100B5B899 /* UIKit.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 537DCEAC1C35D90A00B5B899 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 537DCEB41C35D90A00B5B899 /* SnapKit.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 56A0DC061C859E30005973AB /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 56A0DC1C1C859E9A005973AB /* SnapKit.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - EE94F60D1AC0F132008767FF /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - EE94F6111AC0F146008767FF /* SnapKit.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; EE94F60E1AC0F136008767FF /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -176,48 +99,16 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - EE94F6091AC0F10A008767FF /* UIKit.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - EECDB3761AC0C9D4006BBC11 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - EE94F60B1AC0F10F008767FF /* AppKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 56A0DC0A1C859E30005973AB /* Example-iOS */ = { - isa = PBXGroup; - children = ( - 56A0DC301C85A20E005973AB /* demos */, - 56A0DC211C859F15005973AB /* AppDelegate.swift */, - 56A0DC0D1C859E30005973AB /* ListViewController.swift */, - 56A0DC121C859E30005973AB /* Assets.xcassets */, - 56A0DC141C859E30005973AB /* LaunchScreen.storyboard */, - 56A0DC171C859E30005973AB /* Info.plist */, - ); - path = "Example-iOS"; - sourceTree = ""; - }; - 56A0DC301C85A20E005973AB /* demos */ = { - isa = PBXGroup; - children = ( - 56A0DC311C85A2C1005973AB /* BasicUIScrollViewController.swift */, - 56A0DC331C85AFBF005973AB /* SimpleLayoutViewController.swift */, - ); - path = demos; - sourceTree = ""; - }; DDC9FD8C1981B4DD009612C7 = { isa = PBXGroup; children = ( EECDB35D1AC0C95C006BBC11 /* Source */, - 56A0DC0A1C859E30005973AB /* Example-iOS */, EE94F60C1AC0F113008767FF /* Frameworks */, DDC9FD961981B4DD009612C7 /* Products */, ); @@ -227,16 +118,84 @@ isa = PBXGroup; children = ( EEBCC9D819CC627D0083B827 /* SnapKit.framework */, - EEBCC9E219CC627E0083B827 /* SnapKit iOS Tests.xctest */, - EECDB37A1AC0C9D4006BBC11 /* SnapKit.framework */, - EECDB3841AC0C9D4006BBC11 /* SnapKit OSX Tests.xctest */, - 537DCE921C35CC8800B5B899 /* SnapKit.framework */, - 537DCEAF1C35D90A00B5B899 /* SnapKit tvOS Tests.xctest */, - 56A0DC091C859E30005973AB /* Example-iOS.app */, + EEBCC9E219CC627E0083B827 /* SnapKit Tests.xctest */, ); name = Products; sourceTree = ""; }; + EE235F581C57858700C08960 /* Extensions */ = { + isa = PBXGroup; + children = ( + EE235FC61C5785E200C08960 /* ConstraintView+Extensions.swift */, + EEF68FAF1D784FB100980C26 /* UILayoutGuide+Extensions.swift */, + EEF68FB31D784FBA00980C26 /* UILayoutSupport+Extensions.swift */, + ); + name = Extensions; + sourceTree = ""; + }; + EE235F591C57859200C08960 /* DSLs */ = { + isa = PBXGroup; + children = ( + EEF68FA51D784A5300980C26 /* ConstraintDSL.swift */, + EE235FBE1C5785DC00C08960 /* ConstraintViewDSL.swift */, + EEF68F9D1D78492400980C26 /* ConstraintLayoutGuideDSL.swift */, + EE235FBF1C5785DC00C08960 /* ConstraintLayoutSupportDSL.swift */, + ); + name = DSLs; + sourceTree = ""; + }; + EE235F5A1C57859900C08960 /* Maker */ = { + isa = PBXGroup; + children = ( + EE235FA61C5785D400C08960 /* ConstraintMaker.swift */, + EE235FA71C5785D400C08960 /* ConstraintMakerFinalizable.swift */, + EE235FA81C5785D400C08960 /* ConstraintMakerPriortizable.swift */, + EE235FA91C5785D400C08960 /* ConstraintMakerEditable.swift */, + EE235FAA1C5785D400C08960 /* ConstraintMakerRelatable.swift */, + EE235FAB1C5785D400C08960 /* ConstraintMakerExtendable.swift */, + ); + name = Maker; + sourceTree = ""; + }; + EE235F5B1C57859E00C08960 /* Targets */ = { + isa = PBXGroup; + children = ( + EE235F8E1C5785CE00C08960 /* ConstraintRelatableTarget.swift */, + EE235F8F1C5785CE00C08960 /* ConstraintConstantTarget.swift */, + EE235F901C5785CE00C08960 /* ConstraintPriorityTarget.swift */, + EE235F911C5785CE00C08960 /* ConstraintMultiplierTarget.swift */, + EE235F921C5785CE00C08960 /* ConstraintOffsetTarget.swift */, + EE235F931C5785CE00C08960 /* ConstraintInsetTarget.swift */, + ); + name = Targets; + sourceTree = ""; + }; + EE235F5C1C5785A400C08960 /* Models */ = { + isa = PBXGroup; + children = ( + EE235F621C5785C600C08960 /* Constraint.swift */, + EE235F631C5785C600C08960 /* ConstraintDescription.swift */, + EE235F641C5785C600C08960 /* ConstraintInsets.swift */, + EE235F651C5785C600C08960 /* ConstraintConfig.swift */, + EE235F661C5785C600C08960 /* ConstraintView.swift */, + EEF68FBB1D78653000980C26 /* ConstraintLayoutGuide.swift */, + EEF68FBF1D7865AA00980C26 /* ConstraintLayoutSupport.swift */, + EE235F681C5785C600C08960 /* ConstraintRelation.swift */, + EE235F6A1C5785C600C08960 /* ConstraintAttributes.swift */, + EE235F6B1C5785C600C08960 /* ConstraintItem.swift */, + EE235F6C1C5785C600C08960 /* LayoutConstraint.swift */, + ); + name = Models; + sourceTree = ""; + }; + EE235F5D1C5785AC00C08960 /* Debugging */ = { + isa = PBXGroup; + children = ( + EE235F5E1C5785BC00C08960 /* Debugging.swift */, + ); + name = Debugging; + sourceTree = ""; + }; EE94F60C1AC0F113008767FF /* Frameworks */ = { isa = PBXGroup; children = ( @@ -251,18 +210,12 @@ isa = PBXGroup; children = ( EECDB3661AC0C95C006BBC11 /* SnapKit.h */, - EEFCF32E1AD926AE00A425FA /* SnapKit.swift */, - EECDB35E1AC0C95C006BBC11 /* Constraint.swift */, - EEFCF3311AD9432400A425FA /* ConstraintDescription.swift */, - EECDB3611AC0C95C006BBC11 /* ConstraintMaker.swift */, - EECDB3671AC0C95C006BBC11 /* View+SnapKit.swift */, - EE4910971B19A26000A54F1F /* ViewController+SnapKit.swift */, - EECDB3601AC0C95C006BBC11 /* ConstraintItem.swift */, - EECDB3631AC0C95C006BBC11 /* EdgeInsets.swift */, - EECDB3651AC0C95C006BBC11 /* LayoutConstraint.swift */, - EEFCF32B1AD910B900A425FA /* Debugging.swift */, - EECDB3621AC0C95C006BBC11 /* ConstraintRelation.swift */, - EECDB35F1AC0C95C006BBC11 /* ConstraintAttributes.swift */, + EE235F581C57858700C08960 /* Extensions */, + EE235F591C57859200C08960 /* DSLs */, + EE235F5A1C57859900C08960 /* Maker */, + EE235F5B1C57859E00C08960 /* Targets */, + EE235F5C1C5785A400C08960 /* Models */, + EE235F5D1C5785AC00C08960 /* Debugging */, EECDB36B1AC0C967006BBC11 /* Supporting Files */, EECDB3681AC0C95C006BBC11 /* Tests */, ); @@ -290,14 +243,6 @@ /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ - 537DCE8F1C35CC8800B5B899 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 537DCEA01C35CDF800B5B899 /* SnapKit.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; EEBCC9D519CC627D0083B827 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -306,74 +251,12 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - EECDB3771AC0C9D4006BBC11 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - EECDB39D1AC0CC03006BBC11 /* SnapKit.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ - 537DCE911C35CC8800B5B899 /* SnapKit tvOS */ = { + EEBCC9D719CC627D0083B827 /* SnapKit */ = { isa = PBXNativeTarget; - buildConfigurationList = 537DCE991C35CC8800B5B899 /* Build configuration list for PBXNativeTarget "SnapKit tvOS" */; - buildPhases = ( - 537DCE8D1C35CC8800B5B899 /* Sources */, - 537DCE8E1C35CC8800B5B899 /* Frameworks */, - 537DCE8F1C35CC8800B5B899 /* Headers */, - 537DCE901C35CC8800B5B899 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = "SnapKit tvOS"; - productName = "SnapKit tvOS"; - productReference = 537DCE921C35CC8800B5B899 /* SnapKit.framework */; - productType = "com.apple.product-type.framework"; - }; - 537DCEAE1C35D90A00B5B899 /* SnapKit tvOS Tests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 537DCEB91C35D90A00B5B899 /* Build configuration list for PBXNativeTarget "SnapKit tvOS Tests" */; - buildPhases = ( - 537DCEAB1C35D90A00B5B899 /* Sources */, - 537DCEAC1C35D90A00B5B899 /* Frameworks */, - 537DCEAD1C35D90A00B5B899 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = "SnapKit tvOS Tests"; - productName = "SnapKit tvOS Tests"; - productReference = 537DCEAF1C35D90A00B5B899 /* SnapKit tvOS Tests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; - 56A0DC081C859E30005973AB /* Example-iOS */ = { - isa = PBXNativeTarget; - buildConfigurationList = 56A0DC1A1C859E30005973AB /* Build configuration list for PBXNativeTarget "Example-iOS" */; - buildPhases = ( - 56A0DC051C859E30005973AB /* Sources */, - 56A0DC061C859E30005973AB /* Frameworks */, - 56A0DC071C859E30005973AB /* Resources */, - 56A0DC201C859E9A005973AB /* Embed Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 56A0DC1F1C859E9A005973AB /* PBXTargetDependency */, - ); - name = "Example-iOS"; - productName = "Example-iOS"; - productReference = 56A0DC091C859E30005973AB /* Example-iOS.app */; - productType = "com.apple.product-type.application"; - }; - EEBCC9D719CC627D0083B827 /* SnapKit iOS */ = { - isa = PBXNativeTarget; - buildConfigurationList = EEBCC9E819CC627E0083B827 /* Build configuration list for PBXNativeTarget "SnapKit iOS" */; + buildConfigurationList = EEBCC9E819CC627E0083B827 /* Build configuration list for PBXNativeTarget "SnapKit" */; buildPhases = ( EEBCC9D319CC627D0083B827 /* Sources */, EEBCC9D419CC627D0083B827 /* Frameworks */, @@ -384,14 +267,14 @@ ); dependencies = ( ); - name = "SnapKit iOS"; + name = SnapKit; productName = SnapKit; productReference = EEBCC9D819CC627D0083B827 /* SnapKit.framework */; productType = "com.apple.product-type.framework"; }; - EEBCC9E119CC627D0083B827 /* SnapKit iOS Tests */ = { + EEBCC9E119CC627D0083B827 /* SnapKit Tests */ = { isa = PBXNativeTarget; - buildConfigurationList = EEBCC9EB19CC627E0083B827 /* Build configuration list for PBXNativeTarget "SnapKit iOS Tests" */; + buildConfigurationList = EEBCC9EB19CC627E0083B827 /* Build configuration list for PBXNativeTarget "SnapKit Tests" */; buildPhases = ( EEBCC9DE19CC627D0083B827 /* Sources */, EE94F60E1AC0F136008767FF /* Frameworks */, @@ -401,45 +284,9 @@ ); dependencies = ( ); - name = "SnapKit iOS Tests"; + name = "SnapKit Tests"; productName = SnapKitTests; - productReference = EEBCC9E219CC627E0083B827 /* SnapKit iOS Tests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; - EECDB3791AC0C9D4006BBC11 /* SnapKit OSX */ = { - isa = PBXNativeTarget; - buildConfigurationList = EECDB38D1AC0C9D4006BBC11 /* Build configuration list for PBXNativeTarget "SnapKit OSX" */; - buildPhases = ( - EECDB3751AC0C9D4006BBC11 /* Sources */, - EECDB3761AC0C9D4006BBC11 /* Frameworks */, - EECDB3771AC0C9D4006BBC11 /* Headers */, - EECDB3781AC0C9D4006BBC11 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = "SnapKit OSX"; - productName = "SnapKit OSX"; - productReference = EECDB37A1AC0C9D4006BBC11 /* SnapKit.framework */; - productType = "com.apple.product-type.framework"; - }; - EECDB3831AC0C9D4006BBC11 /* SnapKit OSX Tests */ = { - isa = PBXNativeTarget; - buildConfigurationList = EECDB3901AC0C9D4006BBC11 /* Build configuration list for PBXNativeTarget "SnapKit OSX Tests" */; - buildPhases = ( - EECDB3801AC0C9D4006BBC11 /* Sources */, - EE94F60D1AC0F132008767FF /* Frameworks */, - EECDB3821AC0C9D4006BBC11 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - EECDB3871AC0C9D4006BBC11 /* PBXTargetDependency */, - ); - name = "SnapKit OSX Tests"; - productName = "SnapKit OSXTests"; - productReference = EECDB3841AC0C9D4006BBC11 /* SnapKit OSX Tests.xctest */; + productReference = EEBCC9E219CC627E0083B827 /* SnapKit Tests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; /* End PBXNativeTarget section */ @@ -452,17 +299,6 @@ LastUpgradeCheck = 0800; ORGANIZATIONNAME = "SnapKit Team"; TargetAttributes = { - 537DCE911C35CC8800B5B899 = { - CreatedOnToolsVersion = 7.2; - LastSwiftMigration = 0800; - }; - 537DCEAE1C35D90A00B5B899 = { - CreatedOnToolsVersion = 7.2; - LastSwiftMigration = 0800; - }; - 56A0DC081C859E30005973AB = { - CreatedOnToolsVersion = 7.2.1; - }; EEBCC9D719CC627D0083B827 = { CreatedOnToolsVersion = 6.0; LastSwiftMigration = 0800; @@ -470,14 +306,7 @@ EEBCC9E119CC627D0083B827 = { CreatedOnToolsVersion = 6.0; LastSwiftMigration = 0800; - }; - EECDB3791AC0C9D4006BBC11 = { - CreatedOnToolsVersion = 6.2; - LastSwiftMigration = 0800; - }; - EECDB3831AC0C9D4006BBC11 = { - CreatedOnToolsVersion = 6.2; - LastSwiftMigration = 0800; + ProvisioningStyle = Automatic; }; }; }; @@ -494,41 +323,13 @@ projectDirPath = ""; projectRoot = ""; targets = ( - EEBCC9D719CC627D0083B827 /* SnapKit iOS */, - 537DCE911C35CC8800B5B899 /* SnapKit tvOS */, - EECDB3791AC0C9D4006BBC11 /* SnapKit OSX */, - EEBCC9E119CC627D0083B827 /* SnapKit iOS Tests */, - 537DCEAE1C35D90A00B5B899 /* SnapKit tvOS Tests */, - EECDB3831AC0C9D4006BBC11 /* SnapKit OSX Tests */, - 56A0DC081C859E30005973AB /* Example-iOS */, + EEBCC9D719CC627D0083B827 /* SnapKit */, + EEBCC9E119CC627D0083B827 /* SnapKit Tests */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ - 537DCE901C35CC8800B5B899 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 537DCEAD1C35D90A00B5B899 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 56A0DC071C859E30005973AB /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 56A0DC161C859E30005973AB /* LaunchScreen.storyboard in Resources */, - 56A0DC131C859E30005973AB /* Assets.xcassets in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; EEBCC9D619CC627D0083B827 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -543,77 +344,44 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - EECDB3781AC0C9D4006BBC11 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - EECDB3821AC0C9D4006BBC11 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ - 537DCE8D1C35CC8800B5B899 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 537DCEA61C35CE2000B5B899 /* LayoutConstraint.swift in Sources */, - 537DCE9F1C35CDB700B5B899 /* ConstraintItem.swift in Sources */, - 537DCEA81C35CE3800B5B899 /* ConstraintRelation.swift in Sources */, - 537DCE9D1C35CDA300B5B899 /* SnapKit.swift in Sources */, - 537DCEA51C35CE1B00B5B899 /* EdgeInsets.swift in Sources */, - 537DCE9C1C35CD9A00B5B899 /* Constraint.swift in Sources */, - 537DCEA41C35CE1500B5B899 /* ViewController+SnapKit.swift in Sources */, - 537DCE9E1C35CDAA00B5B899 /* Debugging.swift in Sources */, - 537DCEA11C35CE0000B5B899 /* ConstraintDescription.swift in Sources */, - 537DCEA91C35CE3E00B5B899 /* ConstraintAttributes.swift in Sources */, - 537DCEA31C35CE0900B5B899 /* View+SnapKit.swift in Sources */, - 537DCEA21C35CE0500B5B899 /* ConstraintMaker.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 537DCEAB1C35D90A00B5B899 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 537DCEBA1C35DA9700B5B899 /* Tests.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 56A0DC051C859E30005973AB /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 56A0DC341C85AFBF005973AB /* SimpleLayoutViewController.swift in Sources */, - 56A0DC221C859F15005973AB /* AppDelegate.swift in Sources */, - 56A0DC321C85A2C1005973AB /* BasicUIScrollViewController.swift in Sources */, - 56A0DC0E1C859E30005973AB /* ListViewController.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; EEBCC9D319CC627D0083B827 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - EECDB36C1AC0C9A6006BBC11 /* Constraint.swift in Sources */, - EEFCF32F1AD926AE00A425FA /* SnapKit.swift in Sources */, - EEFCF32C1AD910B900A425FA /* Debugging.swift in Sources */, - EECDB3701AC0C9A6006BBC11 /* ConstraintRelation.swift in Sources */, - EEFCF3321AD9432400A425FA /* ConstraintDescription.swift in Sources */, - EECDB3731AC0C9A6006BBC11 /* View+SnapKit.swift in Sources */, - EECDB3711AC0C9A6006BBC11 /* EdgeInsets.swift in Sources */, - EE4910981B19A26000A54F1F /* ViewController+SnapKit.swift in Sources */, - EECDB36F1AC0C9A6006BBC11 /* ConstraintMaker.swift in Sources */, - EECDB36D1AC0C9A6006BBC11 /* ConstraintAttributes.swift in Sources */, - EECDB3721AC0C9A6006BBC11 /* LayoutConstraint.swift in Sources */, - EECDB36E1AC0C9A6006BBC11 /* ConstraintItem.swift in Sources */, + EE235F731C5785C600C08960 /* ConstraintInsets.swift in Sources */, + EE235FAF1C5785D400C08960 /* ConstraintMakerFinalizable.swift in Sources */, + EE235F971C5785CE00C08960 /* ConstraintConstantTarget.swift in Sources */, + EE235FC81C5785E200C08960 /* ConstraintView+Extensions.swift in Sources */, + EE235FB81C5785D400C08960 /* ConstraintMakerRelatable.swift in Sources */, + EE235F851C5785C600C08960 /* ConstraintAttributes.swift in Sources */, + EE235FA01C5785CE00C08960 /* ConstraintOffsetTarget.swift in Sources */, + EEF68F9E1D78492400980C26 /* ConstraintLayoutGuideDSL.swift in Sources */, + EE235FB51C5785D400C08960 /* ConstraintMakerEditable.swift in Sources */, + EEF68FBC1D78653000980C26 /* ConstraintLayoutGuide.swift in Sources */, + EE235FAC1C5785D400C08960 /* ConstraintMaker.swift in Sources */, + EE235F941C5785CE00C08960 /* ConstraintRelatableTarget.swift in Sources */, + EEF68FA61D784A5300980C26 /* ConstraintDSL.swift in Sources */, + EE235FBB1C5785D400C08960 /* ConstraintMakerExtendable.swift in Sources */, + EE235F881C5785C600C08960 /* ConstraintItem.swift in Sources */, + EE235F9A1C5785CE00C08960 /* ConstraintPriorityTarget.swift in Sources */, + EEF68FC01D7865AA00980C26 /* ConstraintLayoutSupport.swift in Sources */, + EEF68FB01D784FB100980C26 /* UILayoutGuide+Extensions.swift in Sources */, + EE235F761C5785C600C08960 /* ConstraintConfig.swift in Sources */, + EE235F6D1C5785C600C08960 /* Constraint.swift in Sources */, + EE235F791C5785C600C08960 /* ConstraintView.swift in Sources */, + EE235FB21C5785D400C08960 /* ConstraintMakerPriortizable.swift in Sources */, + EE235F8B1C5785C600C08960 /* LayoutConstraint.swift in Sources */, + EE235FA31C5785CE00C08960 /* ConstraintInsetTarget.swift in Sources */, + EE235F9D1C5785CE00C08960 /* ConstraintMultiplierTarget.swift in Sources */, + EE235FC01C5785DC00C08960 /* ConstraintViewDSL.swift in Sources */, + EE235F5F1C5785BC00C08960 /* Debugging.swift in Sources */, + EE235FC31C5785DC00C08960 /* ConstraintLayoutSupportDSL.swift in Sources */, + EE235F7F1C5785C600C08960 /* ConstraintRelation.swift in Sources */, + EEF68FB41D784FBA00980C26 /* UILayoutSupport+Extensions.swift in Sources */, + EE235F701C5785C600C08960 /* ConstraintDescription.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -625,178 +393,9 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - EECDB3751AC0C9D4006BBC11 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - EECDB3951AC0CBFF006BBC11 /* Constraint.swift in Sources */, - EEFCF3301AD92C2200A425FA /* SnapKit.swift in Sources */, - EEFCF32D1AD9250C00A425FA /* Debugging.swift in Sources */, - EECDB3991AC0CBFF006BBC11 /* ConstraintRelation.swift in Sources */, - EEFCF3331AD9432400A425FA /* ConstraintDescription.swift in Sources */, - EECDB39C1AC0CBFF006BBC11 /* View+SnapKit.swift in Sources */, - EECDB39A1AC0CBFF006BBC11 /* EdgeInsets.swift in Sources */, - EECDB3981AC0CBFF006BBC11 /* ConstraintMaker.swift in Sources */, - EECDB3961AC0CBFF006BBC11 /* ConstraintAttributes.swift in Sources */, - EECDB39B1AC0CBFF006BBC11 /* LayoutConstraint.swift in Sources */, - EECDB3971AC0CBFF006BBC11 /* ConstraintItem.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - EECDB3801AC0C9D4006BBC11 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - EECDB3941AC0CB52006BBC11 /* Tests.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXSourcesBuildPhase section */ -/* Begin PBXTargetDependency section */ - 56A0DC1F1C859E9A005973AB /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = EEBCC9D719CC627D0083B827 /* SnapKit iOS */; - targetProxy = 56A0DC1E1C859E9A005973AB /* PBXContainerItemProxy */; - }; - EECDB3871AC0C9D4006BBC11 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = EECDB3791AC0C9D4006BBC11 /* SnapKit OSX */; - targetProxy = EECDB3861AC0C9D4006BBC11 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin PBXVariantGroup section */ - 56A0DC141C859E30005973AB /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 56A0DC151C859E30005973AB /* Base */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - /* Begin XCBuildConfiguration section */ - 537DCE971C35CC8800B5B899 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - APPLICATION_EXTENSION_API_ONLY = YES; - CURRENT_PROJECT_VERSION = 1; - DEBUG_INFORMATION_FORMAT = dwarf; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_NO_COMMON_BLOCKS = YES; - INFOPLIST_FILE = "$(SRCROOT)/Source/Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.snapkit.SnapKit; - PRODUCT_NAME = SnapKit; - SDKROOT = appletvos; - SKIP_INSTALL = YES; - SWIFT_VERSION = 2.3; - TARGETED_DEVICE_FAMILY = 3; - TVOS_DEPLOYMENT_TARGET = 9.0; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Debug; - }; - 537DCE981C35CC8800B5B899 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - APPLICATION_EXTENSION_API_ONLY = YES; - COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_NO_COMMON_BLOCKS = YES; - INFOPLIST_FILE = "$(SRCROOT)/Source/Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = io.snapkit.SnapKit; - PRODUCT_NAME = SnapKit; - SDKROOT = appletvos; - SKIP_INSTALL = YES; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - SWIFT_VERSION = 2.3; - TARGETED_DEVICE_FAMILY = 3; - TVOS_DEPLOYMENT_TARGET = 9.0; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Release; - }; - 537DCEB71C35D90A00B5B899 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - DEBUG_INFORMATION_FORMAT = dwarf; - GCC_NO_COMMON_BLOCKS = YES; - INFOPLIST_FILE = "$(SRCROOT)/Tests/Info.plist"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = "io.snapkit.$(PRODUCT_NAME:rfc1034identifier)"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = appletvos; - SWIFT_VERSION = 2.3; - TVOS_DEPLOYMENT_TARGET = 9.1; - }; - name = Debug; - }; - 537DCEB81C35D90A00B5B899 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_NO_COMMON_BLOCKS = YES; - INFOPLIST_FILE = "$(SRCROOT)/Tests/Info.plist"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = "io.snapkit.$(PRODUCT_NAME:rfc1034identifier)"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = appletvos; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - SWIFT_VERSION = 2.3; - TVOS_DEPLOYMENT_TARGET = 9.1; - }; - name = Release; - }; - 56A0DC181C859E30005973AB /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - DEBUG_INFORMATION_FORMAT = dwarf; - GCC_NO_COMMON_BLOCKS = YES; - INFOPLIST_FILE = "Example-iOS/Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = "io.snapkit.Example-iOS"; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 56A0DC191C859E30005973AB /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_NO_COMMON_BLOCKS = YES; - INFOPLIST_FILE = "Example-iOS/Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = "io.snapkit.Example-iOS"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - }; - name = Release; - }; DDC9FDAF1981B4DD009612C7 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -810,10 +409,8 @@ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -836,12 +433,14 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MACOSX_DEPLOYMENT_TARGET = 10.9; + MACOSX_DEPLOYMENT_TARGET = 10.10; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = "iphonesimulator iphoneos appletvsimulator appletvos macosx"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - TARGETED_DEVICE_FAMILY = "1,2"; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2,3,4"; }; name = Debug; }; @@ -858,10 +457,8 @@ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; @@ -877,10 +474,12 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MACOSX_DEPLOYMENT_TARGET = 10.9; + MACOSX_DEPLOYMENT_TARGET = 10.10; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; + SUPPORTED_PLATFORMS = "iphonesimulator iphoneos appletvsimulator appletvos macosx"; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = "1,2,3,4"; VALIDATE_PRODUCT = YES; }; name = Release; @@ -889,6 +488,7 @@ isa = XCBuildConfiguration; buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; + CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; @@ -900,8 +500,7 @@ PRODUCT_BUNDLE_IDENTIFIER = "io.snapkit.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = SnapKit; SKIP_INSTALL = YES; - SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; - SWIFT_VERSION = 2.3; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; @@ -911,6 +510,7 @@ isa = XCBuildConfiguration; buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; + CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; @@ -922,9 +522,7 @@ PRODUCT_BUNDLE_IDENTIFIER = "io.snapkit.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = SnapKit; SKIP_INSTALL = YES; - SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - SWIFT_VERSION = 2.3; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; @@ -933,149 +531,33 @@ EEBCC9EC19CC627E0083B827 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - FRAMEWORK_SEARCH_PATHS = "$(inherited)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = "$(SRCROOT)/Tests/Info.plist"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + 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)"; - SWIFT_VERSION = 2.3; + SWIFT_VERSION = 3.0; }; name = Debug; }; EEBCC9ED19CC627E0083B827 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - FRAMEWORK_SEARCH_PATHS = "$(inherited)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = "$(SRCROOT)/Tests/Info.plist"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + 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)"; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - SWIFT_VERSION = 2.3; - }; - name = Release; - }; - EECDB38E1AC0C9D4006BBC11 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - APPLICATION_EXTENSION_API_ONLY = YES; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - FRAMEWORK_VERSION = A; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - INFOPLIST_FILE = "$(SRCROOT)/Source/Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.10; - PRODUCT_BUNDLE_IDENTIFIER = "io.snapkit.$(PRODUCT_NAME:rfc1034identifier)"; - PRODUCT_NAME = SnapKit; - SDKROOT = macosx; - SKIP_INSTALL = YES; - SUPPORTED_PLATFORMS = macosx; - SWIFT_VERSION = 2.3; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Debug; - }; - EECDB38F1AC0C9D4006BBC11 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - APPLICATION_EXTENSION_API_ONLY = YES; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - FRAMEWORK_VERSION = A; - INFOPLIST_FILE = "$(SRCROOT)/Source/Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.10; - PRODUCT_BUNDLE_IDENTIFIER = "io.snapkit.$(PRODUCT_NAME:rfc1034identifier)"; - PRODUCT_NAME = SnapKit; - SDKROOT = macosx; - SKIP_INSTALL = YES; - SUPPORTED_PLATFORMS = macosx; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - SWIFT_VERSION = 2.3; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Release; - }; - EECDB3911AC0C9D4006BBC11 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - COMBINE_HIDPI_IMAGES = YES; - FRAMEWORK_SEARCH_PATHS = "$(inherited)"; - INFOPLIST_FILE = "$(SRCROOT)/Tests/Info.plist"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.10; - PRODUCT_BUNDLE_IDENTIFIER = "io.snapkit.$(PRODUCT_NAME:rfc1034identifier)"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx; - SWIFT_VERSION = 2.3; - }; - name = Debug; - }; - EECDB3921AC0C9D4006BBC11 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - COMBINE_HIDPI_IMAGES = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - FRAMEWORK_SEARCH_PATHS = "$(inherited)"; - INFOPLIST_FILE = "$(SRCROOT)/Tests/Info.plist"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.10; - PRODUCT_BUNDLE_IDENTIFIER = "io.snapkit.$(PRODUCT_NAME:rfc1034identifier)"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - SWIFT_VERSION = 2.3; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 3.0; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 537DCE991C35CC8800B5B899 /* Build configuration list for PBXNativeTarget "SnapKit tvOS" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 537DCE971C35CC8800B5B899 /* Debug */, - 537DCE981C35CC8800B5B899 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 537DCEB91C35D90A00B5B899 /* Build configuration list for PBXNativeTarget "SnapKit tvOS Tests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 537DCEB71C35D90A00B5B899 /* Debug */, - 537DCEB81C35D90A00B5B899 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 56A0DC1A1C859E30005973AB /* Build configuration list for PBXNativeTarget "Example-iOS" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 56A0DC181C859E30005973AB /* Debug */, - 56A0DC191C859E30005973AB /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; DDC9FD901981B4DD009612C7 /* Build configuration list for PBXProject "SnapKit" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -1085,7 +567,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - EEBCC9E819CC627E0083B827 /* Build configuration list for PBXNativeTarget "SnapKit iOS" */ = { + EEBCC9E819CC627E0083B827 /* Build configuration list for PBXNativeTarget "SnapKit" */ = { isa = XCConfigurationList; buildConfigurations = ( EEBCC9E919CC627E0083B827 /* Debug */, @@ -1094,7 +576,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - EEBCC9EB19CC627E0083B827 /* Build configuration list for PBXNativeTarget "SnapKit iOS Tests" */ = { + EEBCC9EB19CC627E0083B827 /* Build configuration list for PBXNativeTarget "SnapKit Tests" */ = { isa = XCConfigurationList; buildConfigurations = ( EEBCC9EC19CC627E0083B827 /* Debug */, @@ -1103,24 +585,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - EECDB38D1AC0C9D4006BBC11 /* Build configuration list for PBXNativeTarget "SnapKit OSX" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - EECDB38E1AC0C9D4006BBC11 /* Debug */, - EECDB38F1AC0C9D4006BBC11 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - EECDB3901AC0C9D4006BBC11 /* Build configuration list for PBXNativeTarget "SnapKit OSX Tests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - EECDB3911AC0C9D4006BBC11 /* Debug */, - EECDB3921AC0C9D4006BBC11 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; /* End XCConfigurationList section */ }; rootObject = DDC9FD8D1981B4DD009612C7 /* Project object */; diff --git a/SnapKit.xcodeproj/xcshareddata/xcschemes/SnapKit OSX.xcscheme b/SnapKit.xcodeproj/xcshareddata/xcschemes/SnapKit OSX.xcscheme deleted file mode 100644 index cd7e6f3..0000000 --- a/SnapKit.xcodeproj/xcshareddata/xcschemes/SnapKit OSX.xcscheme +++ /dev/null @@ -1,113 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/SnapKit.xcodeproj/xcshareddata/xcschemes/SnapKit Tests.xcscheme b/SnapKit.xcodeproj/xcshareddata/xcschemes/SnapKit Tests.xcscheme new file mode 100644 index 0000000..67d5136 --- /dev/null +++ b/SnapKit.xcodeproj/xcshareddata/xcschemes/SnapKit Tests.xcscheme @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SnapKit.xcodeproj/xcshareddata/xcschemes/SnapKit tvOS.xcscheme b/SnapKit.xcodeproj/xcshareddata/xcschemes/SnapKit tvOS.xcscheme deleted file mode 100644 index fe33cb3..0000000 --- a/SnapKit.xcodeproj/xcshareddata/xcschemes/SnapKit tvOS.xcscheme +++ /dev/null @@ -1,113 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/SnapKit.xcodeproj/xcshareddata/xcschemes/SnapKit iOS.xcscheme b/SnapKit.xcodeproj/xcshareddata/xcschemes/SnapKit.xcscheme similarity index 89% rename from SnapKit.xcodeproj/xcshareddata/xcschemes/SnapKit iOS.xcscheme rename to SnapKit.xcodeproj/xcshareddata/xcschemes/SnapKit.xcscheme index 2f1aed4..c8f3ec9 100644 --- a/SnapKit.xcodeproj/xcshareddata/xcschemes/SnapKit iOS.xcscheme +++ b/SnapKit.xcodeproj/xcshareddata/xcschemes/SnapKit.xcscheme @@ -16,7 +16,7 @@ BuildableIdentifier = "primary" BlueprintIdentifier = "EEBCC9D719CC627D0083B827" BuildableName = "SnapKit.framework" - BlueprintName = "SnapKit iOS" + BlueprintName = "SnapKit" ReferencedContainer = "container:SnapKit.xcodeproj"> @@ -28,9 +28,9 @@ buildForAnalyzing = "YES"> @@ -47,8 +47,8 @@ @@ -58,7 +58,7 @@ BuildableIdentifier = "primary" BlueprintIdentifier = "EEBCC9D719CC627D0083B827" BuildableName = "SnapKit.framework" - BlueprintName = "SnapKit iOS" + BlueprintName = "SnapKit" ReferencedContainer = "container:SnapKit.xcodeproj"> @@ -80,7 +80,7 @@ BuildableIdentifier = "primary" BlueprintIdentifier = "EEBCC9D719CC627D0083B827" BuildableName = "SnapKit.framework" - BlueprintName = "SnapKit iOS" + BlueprintName = "SnapKit" ReferencedContainer = "container:SnapKit.xcodeproj"> @@ -98,7 +98,7 @@ BuildableIdentifier = "primary" BlueprintIdentifier = "EEBCC9D719CC627D0083B827" BuildableName = "SnapKit.framework" - BlueprintName = "SnapKit iOS" + BlueprintName = "SnapKit" ReferencedContainer = "container:SnapKit.xcodeproj"> diff --git a/Source/Constraint.swift b/Source/Constraint.swift index 0238149..9928cde 100644 --- a/Source/Constraint.swift +++ b/Source/Constraint.swift @@ -22,496 +22,229 @@ // THE SOFTWARE. #if os(iOS) || os(tvOS) -import UIKit + import UIKit #else -import AppKit + import AppKit #endif -/** - Used to expose API's for a Constraint -*/ public class Constraint { - public func install() -> [LayoutConstraint] { fatalError("Must be implemented by Concrete subclass.") } - public func uninstall() -> Void { fatalError("Must be implemented by Concrete subclass.") } - public func activate() -> Void { fatalError("Must be implemented by Concrete subclass.") } - public func deactivate() -> Void { fatalError("Must be implemented by Concrete subclass.") } + internal let sourceLocation: (String, UInt) + internal let label: String? - public func updateOffset(amount: Float) -> Void { fatalError("Must be implemented by Concrete subclass.") } - public func updateOffset(amount: Double) -> Void { fatalError("Must be implemented by Concrete subclass.") } - public func updateOffset(amount: CGFloat) -> Void { fatalError("Must be implemented by Concrete subclass.") } - public func updateOffset(amount: Int) -> Void { fatalError("Must be implemented by Concrete subclass.") } - public func updateOffset(amount: UInt) -> Void { fatalError("Must be implemented by Concrete subclass.") } - public func updateOffset(amount: CGPoint) -> Void { fatalError("Must be implemented by Concrete subclass.") } - public func updateOffset(amount: CGSize) -> Void { fatalError("Must be implemented by Concrete subclass.") } - public func updateOffset(amount: EdgeInsets) -> Void { fatalError("Must be implemented by Concrete subclass.") } - - public func updateInsets(amount: EdgeInsets) -> Void { fatalError("Must be implemented by Concrete subclass.") } - - public func updatePriority(priority: Float) -> Void { fatalError("Must be implemented by Concrete subclass.") } - public func updatePriority(priority: Double) -> Void { fatalError("Must be implemented by Concrete subclass.") } - public func updatePriority(priority: CGFloat) -> Void { fatalError("Must be implemented by Concrete subclass.") } - public func updatePriority(priority: UInt) -> Void { fatalError("Must be implemented by Concrete subclass.") } - public func updatePriority(priority: Int) -> Void { fatalError("Must be implemented by Concrete subclass.") } - public func updatePriorityRequired() -> Void { fatalError("Must be implemented by Concrete subclass.") } - public func updatePriorityHigh() -> Void { fatalError("Must be implemented by Concrete subclass.") } - public func updatePriorityMedium() -> Void { fatalError("Must be implemented by Concrete subclass.") } - public func updatePriorityLow() -> Void { fatalError("Must be implemented by Concrete subclass.") } - - public var layoutConstraints: [LayoutConstraint] { fatalError("Must be implemented by Concrete subclass.") } - - internal var makerFile: String = "Unknown" - internal var makerLine: UInt = 0 - -} - -/** - Used internally to implement a ConcreteConstraint -*/ -internal class ConcreteConstraint: Constraint { - - internal override func updateOffset(amount: Float) -> Void { - self.constant = amount - } - internal override func updateOffset(amount: Double) -> Void { - self.updateOffset(Float(amount)) - } - internal override func updateOffset(amount: CGFloat) -> Void { - self.updateOffset(Float(amount)) - } - internal override func updateOffset(amount: Int) -> Void { - self.updateOffset(Float(amount)) - } - internal override func updateOffset(amount: UInt) -> Void { - self.updateOffset(Float(amount)) - } - internal override func updateOffset(amount: CGPoint) -> Void { - self.constant = amount - } - internal override func updateOffset(amount: CGSize) -> Void { - self.constant = amount - } - internal override func updateOffset(amount: EdgeInsets) -> Void { - self.constant = amount - } - - internal override func updateInsets(amount: EdgeInsets) -> Void { - self.constant = EdgeInsets(top: amount.top, left: amount.left, bottom: -amount.bottom, right: -amount.right) - } - - internal override func updatePriority(priority: Float) -> Void { - self.priority = priority - } - internal override func updatePriority(priority: Double) -> Void { - self.updatePriority(Float(priority)) - } - internal override func updatePriority(priority: CGFloat) -> Void { - self.updatePriority(Float(priority)) - } - internal override func updatePriority(priority: UInt) -> Void { - self.updatePriority(Float(priority)) - } - internal override func updatePriority(priority: Int) -> Void { - self.updatePriority(Float(priority)) - } - internal override func updatePriorityRequired() -> Void { - self.updatePriority(Float(1000.0)) - } - internal override func updatePriorityHigh() -> Void { - self.updatePriority(Float(750.0)) - } - internal override func updatePriorityMedium() -> Void { - #if os(iOS) || os(tvOS) - self.updatePriority(Float(500.0)) - #else - self.updatePriority(Float(501.0)) - #endif - } - internal override func updatePriorityLow() -> Void { - self.updatePriority(Float(250.0)) - } - - internal override func install() -> [LayoutConstraint] { - return self.installOnView(updateExisting: false, file: self.makerFile, line: self.makerLine) - } - - internal override func uninstall() -> Void { - self.uninstallFromView() - } - - internal override func activate() -> Void { - guard self.installInfo != nil else { - self.install() - return - } - #if SNAPKIT_DEPLOYMENT_LEGACY - guard #available(iOS 8.0, OSX 10.10, *) else { - self.install() - return - } - #endif - let layoutConstraints = self.installInfo!.layoutConstraints.allObjects as! [LayoutConstraint] - if layoutConstraints.count > 0 { - NSLayoutConstraint.activateConstraints(layoutConstraints) - } - } - - internal override func deactivate() -> Void { - guard self.installInfo != nil else { - return - } - #if SNAPKIT_DEPLOYMENT_LEGACY - guard #available(iOS 8.0, OSX 10.10, *) else { - return - } - #endif - let layoutConstraints = self.installInfo!.layoutConstraints.allObjects as! [LayoutConstraint] - if layoutConstraints.count > 0 { - NSLayoutConstraint.deactivateConstraints(layoutConstraints) - } - } - - private let fromItem: ConstraintItem - private let toItem: ConstraintItem + private let from: ConstraintItem + private let to: ConstraintItem private let relation: ConstraintRelation - private let multiplier: Float - private var constant: Any { + private let multiplier: ConstraintMultiplierTarget + private var constant: ConstraintConstantTarget { didSet { - if let installInfo = self.installInfo { - for layoutConstraint in installInfo.layoutConstraints.allObjects as! [LayoutConstraint] { - let attribute = (layoutConstraint.secondAttribute == .NotAnAttribute) ? layoutConstraint.firstAttribute : layoutConstraint.secondAttribute - layoutConstraint.constant = attribute.snp_constantForValue(self.constant) - } - } + self.updateConstantAndPriorityIfNeeded() } } - private var priority: Float { + private var priority: ConstraintPriorityTarget { didSet { - if let installInfo = self.installInfo { - for layoutConstraint in installInfo.layoutConstraints.allObjects as! [LayoutConstraint] { - layoutConstraint.priority = self.priority - } - } + self.updateConstantAndPriorityIfNeeded() } } + private var layoutConstraints: [LayoutConstraint] - private let label: String? + // MARK: Initialization - private var installInfo: ConcreteConstraintInstallInfo? = nil - - override var layoutConstraints: [LayoutConstraint] { - if installInfo == nil { - install() - } - - guard let installInfo = installInfo else { - return [] - } - return installInfo.layoutConstraints.allObjects as! [LayoutConstraint] - } - - internal init(fromItem: ConstraintItem, toItem: ConstraintItem, relation: ConstraintRelation, constant: Any, multiplier: Float, priority: Float, label: String? = nil) { - self.fromItem = fromItem - self.toItem = toItem + internal init(from: ConstraintItem, + to: ConstraintItem, + relation: ConstraintRelation, + sourceLocation: (String, UInt), + label: String?, + multiplier: ConstraintMultiplierTarget, + constant: ConstraintConstantTarget, + priority: ConstraintPriorityTarget) { + self.from = from + self.to = to self.relation = relation - self.constant = constant - self.multiplier = multiplier - self.priority = priority + self.sourceLocation = sourceLocation self.label = label - } - - internal func installOnView(updateExisting updateExisting: Bool = false, file: String? = nil, line: UInt? = nil) -> [LayoutConstraint] { - var installOnView: View? = nil - if self.toItem.view != nil { - installOnView = closestCommonSuperviewFromView(self.fromItem.view, toView: self.toItem.view) - if installOnView == nil { - NSException(name: "Cannot Install Constraint", reason: "No common superview between views (@\(self.makerFile)#\(self.makerLine))", userInfo: nil).raise() - return [] - } - } else { - - if self.fromItem.attributes.isSubsetOf(ConstraintAttributes.Width.union(.Height)) { - installOnView = self.fromItem.view - } else { - installOnView = self.fromItem.view?.superview - if installOnView == nil { - NSException(name: "Cannot Install Constraint", reason: "Missing superview (@\(self.makerFile)#\(self.makerLine))", userInfo: nil).raise() - return [] - } - } - } + self.multiplier = multiplier + self.constant = constant + self.priority = priority + self.layoutConstraints = [] - if let installedOnView = self.installInfo?.view { - if installedOnView != installOnView { - NSException(name: "Cannot Install Constraint", reason: "Already installed on different view. (@\(self.makerFile)#\(self.makerLine))", userInfo: nil).raise() - return [] - } - return self.installInfo?.layoutConstraints.allObjects as? [LayoutConstraint] ?? [] - } - - var newLayoutConstraints = [LayoutConstraint]() - let layoutFromAttributes = self.fromItem.attributes.layoutAttributes - let layoutToAttributes = self.toItem.attributes.layoutAttributes + // get attributes + let layoutFromAttributes = self.from.attributes.layoutAttributes + let layoutToAttributes = self.to.attributes.layoutAttributes // get layout from - let layoutFrom: View? = self.fromItem.view + let layoutFrom: ConstraintView = self.from.view! - // get layout relation - let layoutRelation: NSLayoutRelation = self.relation.layoutRelation + // get relation + let layoutRelation = self.relation.layoutRelation for layoutFromAttribute in layoutFromAttributes { // get layout to attribute - let layoutToAttribute = (layoutToAttributes.count > 0) ? layoutToAttributes[0] : layoutFromAttribute + let layoutToAttribute: NSLayoutAttribute + #if os(iOS) || os(tvOS) + if layoutToAttributes.count > 0 { + if self.from.attributes == .edges && self.to.attributes == .margins { + switch layoutFromAttribute { + case .left: + layoutToAttribute = .leftMargin + case .right: + layoutToAttribute = .rightMargin + case .top: + layoutToAttribute = .topMargin + case .bottom: + layoutToAttribute = .bottomMargin + default: + fatalError() + } + } else if self.from.attributes == .margins && self.to.attributes == .edges { + switch layoutFromAttribute { + case .leftMargin: + layoutToAttribute = .left + case .rightMargin: + layoutToAttribute = .right + case .topMargin: + layoutToAttribute = .top + case .bottomMargin: + layoutToAttribute = .bottom + default: + fatalError() + } + } else if self.from.attributes == self.to.attributes { + layoutToAttribute = layoutFromAttribute + } else { + layoutToAttribute = layoutToAttributes[0] + } + } else { + layoutToAttribute = layoutFromAttribute + } + #else + if layoutToAttributes.count > 0 { + layoutToAttribute = layoutToAttributes[0] + } else { + layoutToAttribute = layoutFromAttribute + } + #endif // get layout constant - let layoutConstant: CGFloat = layoutToAttribute.snp_constantForValue(self.constant) + let layoutConstant: CGFloat = self.constant.constraintConstantTargetValueFor(layoutAttribute: layoutToAttribute) // get layout to - #if os(iOS) || os(tvOS) - var layoutTo: AnyObject? = self.toItem.view ?? self.toItem.layoutSupport - #else - var layoutTo: AnyObject? = self.toItem.view - #endif - if layoutTo == nil && layoutToAttribute != .Width && layoutToAttribute != .Height { - layoutTo = installOnView + var layoutTo: AnyObject? = self.to.target + + // use superview if possible + if layoutTo == nil && layoutToAttribute != .width && layoutToAttribute != .height { + layoutTo = layoutFrom.superview } // create layout constraint let layoutConstraint = LayoutConstraint( - item: layoutFrom!, + item: layoutFrom, attribute: layoutFromAttribute, relatedBy: layoutRelation, toItem: layoutTo, attribute: layoutToAttribute, - multiplier: CGFloat(self.multiplier), - constant: layoutConstant) - layoutConstraint.identifier = self.label + multiplier: self.multiplier.constraintMultiplierTargetValue, + constant: layoutConstant + ) + + // set label + layoutConstraint.label = self.label // set priority - layoutConstraint.priority = self.priority + layoutConstraint.priority = self.priority.constraintPriorityTargetValue // set constraint - layoutConstraint.snp_constraint = self + layoutConstraint.constraint = self - newLayoutConstraints.append(layoutConstraint) + // append + self.layoutConstraints.append(layoutConstraint) } + } + + // MARK: Public + + public func activate() { + self.activateIfNeeded() + } + + public func deactivate() { + self.deactivateIfNeeded() + } + + @discardableResult + public func update(offset: ConstraintOffsetTarget) -> Constraint { + self.constant = offset.constraintOffsetTargetValue + return self + } + + @discardableResult + public func update(inset: ConstraintInsetTarget) -> Constraint { + self.constant = inset.constraintInsetTargetValue + return self + } + + @discardableResult + public func update(priority: ConstraintPriorityTarget) -> Constraint { + self.priority = priority.constraintPriorityTargetValue + return self + } + + @available(*, deprecated:0.40.0, message:"Use update(offset: ConstraintOffsetTarget) instead.") + public func updateOffset(amount: ConstraintOffsetTarget) -> Void { self.update(offset: amount) } + + @available(*, deprecated:0.40.0, message:"Use update(inset: ConstraintInsetTarget) instead.") + public func updateInsets(amount: ConstraintInsetTarget) -> Void { self.update(inset: amount) } + + @available(*, deprecated:0.40.0, message:"Use update(priority: ConstraintPriorityTarget) instead.") + public func updatePriority(amount: ConstraintPriorityTarget) -> Void { self.update(priority: amount) } + + @available(*, obsoleted:0.40.0, message:"Use update(priority: ConstraintPriorityTarget) instead.") + public func updatePriorityRequired() -> Void {} + + @available(*, obsoleted:0.40.0, message:"Use update(priority: ConstraintPriorityTarget) instead.") + public func updatePriorityHigh() -> Void { fatalError("Must be implemented by Concrete subclass.") } + + @available(*, obsoleted:0.40.0, message:"Use update(priority: ConstraintPriorityTarget) instead.") + public func updatePriorityMedium() -> Void { fatalError("Must be implemented by Concrete subclass.") } + + @available(*, obsoleted:0.40.0, message:"Use update(priority: ConstraintPriorityTarget) instead.") + public func updatePriorityLow() -> Void { fatalError("Must be implemented by Concrete subclass.") } + + // MARK: Internal + + internal func updateConstantAndPriorityIfNeeded() { + for layoutConstraint in self.layoutConstraints { + let attribute = (layoutConstraint.secondAttribute == .notAnAttribute) ? layoutConstraint.firstAttribute : layoutConstraint.secondAttribute + layoutConstraint.constant = self.constant.constraintConstantTargetValueFor(layoutAttribute: attribute) + layoutConstraint.priority = self.priority.constraintPriorityTargetValue + } + } + + internal func activateIfNeeded(updatingExisting: Bool = false) { + let view = self.from.view! + let layoutConstraints = self.layoutConstraints + let existingLayoutConstraints = view.snp.layoutConstraints - // special logic for updating - if updateExisting { - // get existing constraints for this view - let existingLayoutConstraints = layoutFrom!.snp_installedLayoutConstraints.reverse() - - // array that will contain only new layout constraints to keep - var newLayoutConstraintsToKeep = [LayoutConstraint]() - - // begin looping - for layoutConstraint in newLayoutConstraints { - // layout constraint that should be updated - var updateLayoutConstraint: LayoutConstraint? = nil - - // loop through existing and check for match - for existingLayoutConstraint in existingLayoutConstraints { - if existingLayoutConstraint == layoutConstraint { - updateLayoutConstraint = existingLayoutConstraint - break - } + if updatingExisting { + for layoutConstraint in layoutConstraints { + let existingLayoutConstraint = existingLayoutConstraints.first { $0 == layoutConstraint } + guard let updateLayoutConstraint = existingLayoutConstraint else { + fatalError("Updated constraint could not find existing matching constraint to update: \(layoutConstraint)") } - // if we have existing one lets just update the constant - if updateLayoutConstraint != nil { - updateLayoutConstraint!.constant = layoutConstraint.constant - } - // otherwise add this layout constraint to new keep list - else { - newLayoutConstraintsToKeep.append(layoutConstraint) - } + let updateLayoutAttribute = (updateLayoutConstraint.secondAttribute == .notAnAttribute) ? updateLayoutConstraint.firstAttribute : updateLayoutConstraint.secondAttribute + updateLayoutConstraint.constant = self.constant.constraintConstantTargetValueFor(layoutAttribute: updateLayoutAttribute) } - - // set constraints to only new ones - newLayoutConstraints = newLayoutConstraintsToKeep - } - - // add constraints - #if SNAPKIT_DEPLOYMENT_LEGACY && !os(OSX) - if #available(iOS 8.0, *) { - NSLayoutConstraint.activateConstraints(newLayoutConstraints) } else { - installOnView!.addConstraints(newLayoutConstraints) + NSLayoutConstraint.activate(layoutConstraints) + view.snp.add(layoutConstraints: layoutConstraints) } - #else - NSLayoutConstraint.activateConstraints(newLayoutConstraints) - #endif - - // set install info - self.installInfo = ConcreteConstraintInstallInfo(view: installOnView, layoutConstraints: NSHashTable.weakObjectsHashTable()) - - // store which layout constraints are installed for this constraint - for layoutConstraint in newLayoutConstraints { - self.installInfo!.layoutConstraints.addObject(layoutConstraint) - } - - // store the layout constraints against the layout from view - layoutFrom!.snp_installedLayoutConstraints += newLayoutConstraints - - // return the new constraints - return newLayoutConstraints } - internal func uninstallFromView() { - if let installInfo = self.installInfo, - let installedLayoutConstraints = installInfo.layoutConstraints.allObjects as? [LayoutConstraint] { - - if installedLayoutConstraints.count > 0 { - // remove the constraints from the UIView's storage - #if SNAPKIT_DEPLOYMENT_LEGACY && !os(OSX) - if #available(iOS 8.0, *) { - NSLayoutConstraint.deactivateConstraints(installedLayoutConstraints) - } else if let installedOnView = installInfo.view { - installedOnView.removeConstraints(installedLayoutConstraints) - } - #else - NSLayoutConstraint.deactivateConstraints(installedLayoutConstraints) - #endif - - // remove the constraints from the from item view - if let fromView = self.fromItem.view { - fromView.snp_installedLayoutConstraints = fromView.snp_installedLayoutConstraints.filter { - return !installedLayoutConstraints.contains($0) - } - } - } - - } - self.installInfo = nil - } - -} - -private struct ConcreteConstraintInstallInfo { - - weak var view: View? = nil - let layoutConstraints: NSHashTable - -} - -private extension NSLayoutAttribute { - - private func snp_constantForValue(value: Any?) -> CGFloat { - // Float - if let float = value as? Float { - return CGFloat(float) - } - // Double - else if let double = value as? Double { - return CGFloat(double) - } - // UInt - else if let int = value as? Int { - return CGFloat(int) - } - // Int - else if let uint = value as? UInt { - return CGFloat(uint) - } - // CGFloat - else if let float = value as? CGFloat { - return float - } - // CGSize - else if let size = value as? CGSize { - if self == .Width { - return size.width - } else if self == .Height { - return size.height - } - } - // CGPoint - else if let point = value as? CGPoint { - #if os(iOS) || os(tvOS) - switch self { - case .Left, .CenterX, .LeftMargin, .CenterXWithinMargins: return point.x - case .Top, .CenterY, .TopMargin, .CenterYWithinMargins, .LastBaseline, .FirstBaseline: return point.y - case .Right, .RightMargin: return point.x - case .Bottom, .BottomMargin: return point.y - case .Leading, .LeadingMargin: return point.x - case .Trailing, .TrailingMargin: return point.x - case .Width, .Height, .NotAnAttribute: return CGFloat(0) - } - #else - switch self { - case .Left, .CenterX: return point.x - case .Top, .CenterY, .LastBaseline: return point.y - case .Right: return point.x - case .Bottom: return point.y - case .Leading: return point.x - case .Trailing: return point.x - case .Width, .Height, .NotAnAttribute: return CGFloat(0) - case .FirstBaseline: return point.y - } - #endif - } - // EdgeInsets - else if let insets = value as? EdgeInsets { - #if os(iOS) || os(tvOS) - switch self { - case .Left, .CenterX, .LeftMargin, .CenterXWithinMargins: return insets.left - case .Top, .CenterY, .TopMargin, .CenterYWithinMargins, .LastBaseline, .FirstBaseline: return insets.top - case .Right, .RightMargin: return insets.right - case .Bottom, .BottomMargin: return insets.bottom - case .Leading, .LeadingMargin: return (Config.interfaceLayoutDirection == .LeftToRight) ? insets.left : -insets.right - case .Trailing, .TrailingMargin: return (Config.interfaceLayoutDirection == .LeftToRight) ? insets.right : -insets.left - case .Width: return -insets.left + insets.right - case .Height: return -insets.top + insets.bottom - case .NotAnAttribute: return CGFloat(0) - } - #else - switch self { - case .Left, .CenterX: return insets.left - case .Top, .CenterY, .LastBaseline: return insets.top - case .Right: return insets.right - case .Bottom: return insets.bottom - case .Leading: return (Config.interfaceLayoutDirection == .LeftToRight) ? insets.left : -insets.right - case .Trailing: return (Config.interfaceLayoutDirection == .LeftToRight) ? insets.right : -insets.left - case .Width: return -insets.left + insets.right - case .Height: return -insets.top + insets.bottom - case .NotAnAttribute: return CGFloat(0) - case .FirstBaseline: return insets.bottom - } - #endif - } - - return CGFloat(0); + internal func deactivateIfNeeded() { + let view = self.from.view! + let layoutConstraints = self.layoutConstraints + NSLayoutConstraint.deactivate(layoutConstraints) + view.snp.remove(layoutConstraints: layoutConstraints) } } - -private func closestCommonSuperviewFromView(fromView: View?, toView: View?) -> View? { - var views = Set() - var fromView = fromView - var toView = toView - repeat { - if let view = toView { - if views.contains(view) { - return view - } - views.insert(view) - toView = view.superview - } - if let view = fromView { - if views.contains(view) { - return view - } - views.insert(view) - fromView = view.superview - } - } while (fromView != nil || toView != nil) - - return nil -} - -private func ==(left: ConcreteConstraint, right: ConcreteConstraint) -> Bool { - return (left.fromItem == right.fromItem && - left.toItem == right.toItem && - left.relation == right.relation && - left.multiplier == right.multiplier && - left.priority == right.priority) -} diff --git a/Source/ConstraintAttributes.swift b/Source/ConstraintAttributes.swift index 304a3c8..7236d24 100644 --- a/Source/ConstraintAttributes.swift +++ b/Source/ConstraintAttributes.swift @@ -1,7 +1,7 @@ // // SnapKit // -// Copyright (c) 2011-2015 SnapKit Team - https://github.com/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 @@ -22,15 +22,13 @@ // THE SOFTWARE. #if os(iOS) || os(tvOS) -import UIKit + import UIKit #else -import AppKit + import AppKit #endif -/** - Used to define `NSLayoutAttributes` in a more concise and composite manner -*/ -internal struct ConstraintAttributes: OptionSetType, BooleanType { + +internal struct ConstraintAttributes: OptionSet { internal init(rawValue: UInt) { self.rawValue = rawValue @@ -48,139 +46,145 @@ internal struct ConstraintAttributes: OptionSetType, BooleanType { internal var boolValue: Bool { return self.rawValue != 0 } internal func toRaw() -> UInt { return self.rawValue } - internal static func fromRaw(raw: UInt) -> ConstraintAttributes? { return self.init(raw) } - internal static func fromMask(raw: UInt) -> ConstraintAttributes { return self.init(raw) } + internal static func fromRaw(_ raw: UInt) -> ConstraintAttributes? { return self.init(raw) } + internal static func fromMask(_ raw: UInt) -> ConstraintAttributes { return self.init(raw) } // 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 Baseline: ConstraintAttributes { return self.init(1024) } + 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) } + + @available(iOS 8.0, OSX 10.11, *) + internal static var firstBaseline: ConstraintAttributes { return self.init(2048) } @available(iOS 8.0, *) - internal static var FirstBaseline: ConstraintAttributes { return self.init(2048) } + internal static var leftMargin: ConstraintAttributes { return self.init(4096) } + @available(iOS 8.0, *) - internal static var LeftMargin: ConstraintAttributes { return self.init(4096) } + internal static var rightMargin: ConstraintAttributes { return self.init(8192) } + @available(iOS 8.0, *) - internal static var RightMargin: ConstraintAttributes { return self.init(8192) } + internal static var topMargin: ConstraintAttributes { return self.init(16384) } + @available(iOS 8.0, *) - internal static var TopMargin: ConstraintAttributes { return self.init(16384) } + internal static var bottomMargin: ConstraintAttributes { return self.init(32768) } + @available(iOS 8.0, *) - internal static var BottomMargin: ConstraintAttributes { return self.init(32768) } + internal static var leadingMargin: ConstraintAttributes { return self.init(65536) } + @available(iOS 8.0, *) - internal static var LeadingMargin: ConstraintAttributes { return self.init(65536) } + internal static var trailingMargin: ConstraintAttributes { return self.init(131072) } + @available(iOS 8.0, *) - internal static var TrailingMargin: ConstraintAttributes { return self.init(131072) } + internal static var centerXWithinMargins: ConstraintAttributes { return self.init(262144) } + @available(iOS 8.0, *) - internal static var CenterXWithinMargins: ConstraintAttributes { return self.init(262144) } - @available(iOS 8.0, *) - internal static var CenterYWithinMargins: ConstraintAttributes { return self.init(524288) } + internal static var centerYWithinMargins: ConstraintAttributes { return self.init(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 self.init(15) } + internal static var size: ConstraintAttributes { return self.init(192) } + internal static var center: ConstraintAttributes { return self.init(768) } @available(iOS 8.0, *) - internal static var Margins: ConstraintAttributes { return self.init(61440) } + internal static var margins: ConstraintAttributes { return self.init(61440) } @available(iOS 8.0, *) - internal static var CenterWithinMargins: ConstraintAttributes { return self.init(786432) } + internal static var centerWithinMargins: ConstraintAttributes { return self.init(786432) } internal var layoutAttributes:[NSLayoutAttribute] { var attrs = [NSLayoutAttribute]() - if (self.contains(ConstraintAttributes.Left)) { - attrs.append(.Left) + if (self.contains(ConstraintAttributes.left)) { + attrs.append(.left) } - if (self.contains(ConstraintAttributes.Top)) { - attrs.append(.Top) + if (self.contains(ConstraintAttributes.top)) { + attrs.append(.top) } - if (self.contains(ConstraintAttributes.Right)) { - attrs.append(.Right) + if (self.contains(ConstraintAttributes.right)) { + attrs.append(.right) } - if (self.contains(ConstraintAttributes.Bottom)) { - attrs.append(.Bottom) + if (self.contains(ConstraintAttributes.bottom)) { + attrs.append(.bottom) } - if (self.contains(ConstraintAttributes.Leading)) { - attrs.append(.Leading) + if (self.contains(ConstraintAttributes.leading)) { + attrs.append(.leading) } - if (self.contains(ConstraintAttributes.Trailing)) { - attrs.append(.Trailing) + if (self.contains(ConstraintAttributes.trailing)) { + attrs.append(.trailing) } - if (self.contains(ConstraintAttributes.Width)) { - attrs.append(.Width) + if (self.contains(ConstraintAttributes.width)) { + attrs.append(.width) } - if (self.contains(ConstraintAttributes.Height)) { - attrs.append(.Height) + if (self.contains(ConstraintAttributes.height)) { + attrs.append(.height) } - if (self.contains(ConstraintAttributes.CenterX)) { - attrs.append(.CenterX) + if (self.contains(ConstraintAttributes.centerX)) { + attrs.append(.centerX) } - if (self.contains(ConstraintAttributes.CenterY)) { - attrs.append(.CenterY) + if (self.contains(ConstraintAttributes.centerY)) { + attrs.append(.centerY) } - if (self.contains(ConstraintAttributes.Baseline)) { - #if swift(>=2.3) - attrs.append(.LastBaseline) - #else - attrs.append(.Baseline) - #endif + if (self.contains(ConstraintAttributes.lastBaseline)) { + attrs.append(.lastBaseline) } #if os(iOS) || os(tvOS) - #if SNAPKIT_DEPLOYMENT_LEGACY - guard #available(iOS 8.0, *) else { - return attrs - } - #endif - if (self.contains(ConstraintAttributes.FirstBaseline)) { - attrs.append(.FirstBaseline) - } - if (self.contains(ConstraintAttributes.LeftMargin)) { - attrs.append(.LeftMargin) - } - if (self.contains(ConstraintAttributes.RightMargin)) { - attrs.append(.RightMargin) - } - if (self.contains(ConstraintAttributes.TopMargin)) { - attrs.append(.TopMargin) - } - if (self.contains(ConstraintAttributes.BottomMargin)) { - attrs.append(.BottomMargin) - } - if (self.contains(ConstraintAttributes.LeadingMargin)) { - attrs.append(.LeadingMargin) - } - if (self.contains(ConstraintAttributes.TrailingMargin)) { - attrs.append(.TrailingMargin) - } - if (self.contains(ConstraintAttributes.CenterXWithinMargins)) { - attrs.append(.CenterXWithinMargins) - } - if (self.contains(ConstraintAttributes.CenterYWithinMargins)) { - attrs.append(.CenterYWithinMargins) - } + if (self.contains(ConstraintAttributes.firstBaseline)) { + attrs.append(.firstBaseline) + } + if (self.contains(ConstraintAttributes.leftMargin)) { + attrs.append(.leftMargin) + } + if (self.contains(ConstraintAttributes.rightMargin)) { + attrs.append(.rightMargin) + } + if (self.contains(ConstraintAttributes.topMargin)) { + attrs.append(.topMargin) + } + if (self.contains(ConstraintAttributes.bottomMargin)) { + attrs.append(.bottomMargin) + } + if (self.contains(ConstraintAttributes.leadingMargin)) { + attrs.append(.leadingMargin) + } + if (self.contains(ConstraintAttributes.trailingMargin)) { + attrs.append(.trailingMargin) + } + if (self.contains(ConstraintAttributes.centerXWithinMargins)) { + attrs.append(.centerXWithinMargins) + } + if (self.contains(ConstraintAttributes.centerYWithinMargins)) { + attrs.append(.centerYWithinMargins) + } #endif return attrs } } -internal func +=(inout left: ConstraintAttributes, right: ConstraintAttributes) { - left.unionInPlace(right) + +internal func + (left: ConstraintAttributes, right: ConstraintAttributes) -> ConstraintAttributes { + return left.union(right) } -internal func -=(inout left: ConstraintAttributes, right: ConstraintAttributes) { - left.subtractInPlace(right) + +internal func +=(left: inout ConstraintAttributes, right: ConstraintAttributes) { + left.formUnion(right) } + +internal func -=(left: inout ConstraintAttributes, right: ConstraintAttributes) { + left.subtract(right) +} + internal func ==(left: ConstraintAttributes, right: ConstraintAttributes) -> Bool { return left.rawValue == right.rawValue } diff --git a/Source/SnapKit.swift b/Source/ConstraintConfig.swift similarity index 68% rename from Source/SnapKit.swift rename to Source/ConstraintConfig.swift index 3aa5181..2746b7d 100644 --- a/Source/SnapKit.swift +++ b/Source/ConstraintConfig.swift @@ -1,7 +1,7 @@ // // SnapKit // -// Copyright (c) 2011-2015 SnapKit Team - https://github.com/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 @@ -22,21 +22,16 @@ // THE SOFTWARE. #if os(iOS) || os(tvOS) -import UIKit -public typealias InterfaceLayoutDirection = UIUserInterfaceLayoutDirection -public typealias LayoutSupport = UILayoutSupport + import UIKit + public typealias ConstraintInterfaceLayoutDirection = UIUserInterfaceLayoutDirection #else -import AppKit -public typealias InterfaceLayoutDirection = NSUserInterfaceLayoutDirection -public class LayoutSupport {} + import AppKit + public typealias ConstraintInterfaceLayoutDirection = NSUserInterfaceLayoutDirection #endif -/** - Used to configure different parts of SnapKit -*/ -public struct Config { + +public struct ConstraintConfig { - /// The interface layout direction - public static var interfaceLayoutDirection = InterfaceLayoutDirection.LeftToRight + public static var interfaceLayoutDirection: ConstraintInterfaceLayoutDirection = .leftToRight -} \ No newline at end of file +} diff --git a/Source/ConstraintConstantTarget.swift b/Source/ConstraintConstantTarget.swift new file mode 100644 index 0000000..8a32519 --- /dev/null +++ b/Source/ConstraintConstantTarget.swift @@ -0,0 +1,147 @@ +// +// 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 protocol ConstraintConstantTarget { +} + +extension CGPoint: ConstraintConstantTarget { +} + +extension CGSize: ConstraintConstantTarget { +} + +extension ConstraintInsets: ConstraintConstantTarget { +} + +extension ConstraintConstantTarget { + + internal func constraintConstantTargetValueFor(layoutAttribute: NSLayoutAttribute) -> CGFloat { + if let value = self as? CGFloat { + return value + } + + if let value = self as? Float { + return CGFloat(value) + } + + if let value = self as? Double { + return CGFloat(value) + } + + if let value = self as? Int { + return CGFloat(value) + } + + if let value = self as? UInt { + return CGFloat(value) + } + + if let value = self as? CGSize { + if layoutAttribute == .width { + return value.width + } else if layoutAttribute == .height { + return value.height + } else { + return 0.0 + } + } + + if let value = self as? CGPoint { + #if os(iOS) || os(tvOS) + switch layoutAttribute { + case .left, .right, .leading, .trailing, .centerX, .leftMargin, .rightMargin, .leadingMargin, .trailingMargin, .centerXWithinMargins: + return value.x + case .top, .bottom, .centerY, .topMargin, .bottomMargin, .centerYWithinMargins, .lastBaseline, .firstBaseline: + return value.y + case .width, .height, .notAnAttribute: + return 0.0 + } + #else + switch layoutAttribute { + case .left, .right, .leading, .trailing, .centerX: + return value.x + case .top, .bottom, .centerY, .lastBaseline, .firstBaseline: + return value.y + case .width, .height, .notAnAttribute: + return 0.0 + } + #endif + } + + if let value = self as? ConstraintInsets { + #if os(iOS) || os(tvOS) + switch layoutAttribute { + case .left, .leftMargin, .centerX, .centerXWithinMargins: + return value.left + case .top, .topMargin, .centerY, .centerYWithinMargins, .lastBaseline, .firstBaseline: + return value.top + case .right, .rightMargin: + return -value.right + case .bottom, .bottomMargin: + return -value.bottom + case .leading, .leadingMargin: + return (ConstraintConfig.interfaceLayoutDirection == .leftToRight) ? value.left : -value.right + case .trailing, .trailingMargin: + return (ConstraintConfig.interfaceLayoutDirection == .leftToRight) ? value.right : -value.left + case .width: + return -(value.left + value.right) + case .height: + return -(value.top + value.bottom) + case .notAnAttribute: + return 0.0 + } + #else + switch layoutAttribute { + case .left, .centerX: + return value.left + case .top, .centerY, .lastBaseline, .firstBaseline: + return value.top + case .right: + return -value.right + case .bottom: + return -value.bottom + case .leading: + return (ConstraintConfig.interfaceLayoutDirection == .leftToRight) ? value.left : -value.right + case .trailing: + return (ConstraintConfig.interfaceLayoutDirection == .leftToRight) ? value.right : -value.left + case .width: + return -(value.left + value.right) + case .height: + return -(value.top + value.bottom) + case .notAnAttribute: + return 0.0 + } + #endif + } + + return 0.0 + } + +} diff --git a/Source/ConstraintDSL.swift b/Source/ConstraintDSL.swift new file mode 100644 index 0000000..837e80b --- /dev/null +++ b/Source/ConstraintDSL.swift @@ -0,0 +1,179 @@ +// +// 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 protocol ConstraintDSL { + + var label: String? { get set } + var target: AnyObject? { get } + +} +extension ConstraintDSL { + + public var label: String? { + get { + return objc_getAssociatedObject(self.target, &labelKey) as? String + } + set { + objc_setAssociatedObject(self.target, &labelKey, newValue, .OBJC_ASSOCIATION_COPY_NONATOMIC) + } + } + +} +private var labelKey: UInt8 = 0 + + +public protocol ConstraintAttributesDSL: ConstraintDSL { +} +extension ConstraintAttributesDSL { + + // MARK: Basics + + public var left: ConstraintItem { + return ConstraintItem(target: self.target, attributes: ConstraintAttributes.left) + } + + public var top: ConstraintItem { + return ConstraintItem(target: self.target, attributes: ConstraintAttributes.top) + } + + public var right: ConstraintItem { + return ConstraintItem(target: self.target, attributes: ConstraintAttributes.right) + } + + public var bottom: ConstraintItem { + return ConstraintItem(target: self.target, attributes: ConstraintAttributes.bottom) + } + + public var leading: ConstraintItem { + return ConstraintItem(target: self.target, attributes: ConstraintAttributes.leading) + } + + public var trailing: ConstraintItem { + return ConstraintItem(target: self.target, attributes: ConstraintAttributes.trailing) + } + + public var width: ConstraintItem { + return ConstraintItem(target: self.target, attributes: ConstraintAttributes.width) + } + + public var height: ConstraintItem { + return ConstraintItem(target: self.target, attributes: ConstraintAttributes.height) + } + + public var centerX: ConstraintItem { + return ConstraintItem(target: self.target, attributes: ConstraintAttributes.centerX) + } + + public var centerY: ConstraintItem { + return ConstraintItem(target: self.target, attributes: ConstraintAttributes.centerY) + } + + public var edges: ConstraintItem { + return ConstraintItem(target: self.target, attributes: ConstraintAttributes.edges) + } + + public var size: ConstraintItem { + return ConstraintItem(target: self.target, attributes: ConstraintAttributes.size) + } + + public var center: ConstraintItem { + return ConstraintItem(target: self.target, attributes: ConstraintAttributes.center) + } + + // MARK: Baselines + + @available(*, deprecated:0.40.0, message:"Use .lastBaseline instead") + public var baseline: ConstraintItem { + return ConstraintItem(target: self.target, attributes: ConstraintAttributes.lastBaseline) + } + + @available(iOS 8.0, OSX 10.11, *) + public var lastBaseline: ConstraintItem { + return ConstraintItem(target: self.target, attributes: ConstraintAttributes.lastBaseline) + } + + @available(iOS 8.0, OSX 10.11, *) + public var firstBaseline: ConstraintItem { + return ConstraintItem(target: self.target, attributes: ConstraintAttributes.firstBaseline) + } + + // MARK: Margins + + @available(iOS 8.0, *) + public var leftMargin: ConstraintItem { + return ConstraintItem(target: self.target, attributes: ConstraintAttributes.leftMargin) + } + + @available(iOS 8.0, *) + public var topMargin: ConstraintItem { + return ConstraintItem(target: self.target, attributes: ConstraintAttributes.topMargin) + } + + @available(iOS 8.0, *) + public var rightMargin: ConstraintItem { + return ConstraintItem(target: self.target, attributes: ConstraintAttributes.rightMargin) + } + + @available(iOS 8.0, *) + public var bottomMargin: ConstraintItem { + return ConstraintItem(target: self.target, attributes: ConstraintAttributes.bottomMargin) + } + + @available(iOS 8.0, *) + public var leadingMargin: ConstraintItem { + return ConstraintItem(target: self.target, attributes: ConstraintAttributes.leadingMargin) + } + + @available(iOS 8.0, *) + public var trailingMargin: ConstraintItem { + return ConstraintItem(target: self.target, attributes: ConstraintAttributes.trailingMargin) + } + + @available(iOS 8.0, *) + public var centerXWithinMargins: ConstraintItem { + return ConstraintItem(target: self.target, attributes: ConstraintAttributes.centerXWithinMargins) + } + + @available(iOS 8.0, *) + public var centerYWithinMargins: ConstraintItem { + return ConstraintItem(target: self.target, attributes: ConstraintAttributes.centerYWithinMargins) + } + + @available(iOS 8.0, *) + public var margins: ConstraintItem { + return ConstraintItem(target: self.target, attributes: ConstraintAttributes.margins) + } + + @available(iOS 8.0, *) + public var centerWithinMargins: ConstraintItem { + return ConstraintItem(target: self.target, attributes: ConstraintAttributes.centerWithinMargins) + } + +} diff --git a/Source/ConstraintDescription.swift b/Source/ConstraintDescription.swift index 384ee30..d961fb5 100644 --- a/Source/ConstraintDescription.swift +++ b/Source/ConstraintDescription.swift @@ -1,7 +1,7 @@ // // SnapKit // -// Copyright (c) 2011-2015 SnapKit Team - https://github.com/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 @@ -22,609 +22,48 @@ // THE SOFTWARE. #if os(iOS) || os(tvOS) -import UIKit + import UIKit #else -import AppKit + import AppKit #endif -/** - Used to expose the final API of a `ConstraintDescription` which allows getting a constraint from it - */ -public protocol ConstraintDescriptionFinalizable: class { - - var constraint: Constraint { get } - - func labeled(label: String) -> ConstraintDescriptionFinalizable - -} -/** - Used to expose priority APIs - */ -public protocol ConstraintDescriptionPriortizable: ConstraintDescriptionFinalizable { +public class ConstraintDescription { - func priority(priority: Float) -> ConstraintDescriptionFinalizable - func priority(priority: Double) -> ConstraintDescriptionFinalizable - func priority(priority: CGFloat) -> ConstraintDescriptionFinalizable - func priority(priority: UInt) -> ConstraintDescriptionFinalizable - func priority(priority: Int) -> ConstraintDescriptionFinalizable - func priorityRequired() -> ConstraintDescriptionFinalizable - func priorityHigh() -> ConstraintDescriptionFinalizable - func priorityMedium() -> ConstraintDescriptionFinalizable - func priorityLow() -> ConstraintDescriptionFinalizable -} - -/** - Used to expose multiplier & constant APIs -*/ -public protocol ConstraintDescriptionEditable: ConstraintDescriptionPriortizable { - - func multipliedBy(amount: Float) -> ConstraintDescriptionEditable - func multipliedBy(amount: Double) -> ConstraintDescriptionEditable - func multipliedBy(amount: CGFloat) -> ConstraintDescriptionEditable - func multipliedBy(amount: Int) -> ConstraintDescriptionEditable - func multipliedBy(amount: UInt) -> ConstraintDescriptionEditable - - func dividedBy(amount: Float) -> ConstraintDescriptionEditable - func dividedBy(amount: Double) -> ConstraintDescriptionEditable - func dividedBy(amount: CGFloat) -> ConstraintDescriptionEditable - func dividedBy(amount: Int) -> ConstraintDescriptionEditable - func dividedBy(amount: UInt) -> ConstraintDescriptionEditable - - func offset(amount: Float) -> ConstraintDescriptionEditable - func offset(amount: Double) -> ConstraintDescriptionEditable - func offset(amount: CGFloat) -> ConstraintDescriptionEditable - func offset(amount: Int) -> ConstraintDescriptionEditable - func offset(amount: UInt) -> ConstraintDescriptionEditable - func offset(amount: CGPoint) -> ConstraintDescriptionEditable - func offset(amount: CGSize) -> ConstraintDescriptionEditable - func offset(amount: EdgeInsets) -> ConstraintDescriptionEditable - - func inset(amount: Float) -> ConstraintDescriptionEditable - func inset(amount: Double) -> ConstraintDescriptionEditable - func inset(amount: CGFloat) -> ConstraintDescriptionEditable - func inset(amount: Int) -> ConstraintDescriptionEditable - func inset(amount: UInt) -> ConstraintDescriptionEditable - func inset(amount: EdgeInsets) -> ConstraintDescriptionEditable -} - -/** - Used to expose relation APIs -*/ -public protocol ConstraintDescriptionRelatable: class { - - func equalTo(other: ConstraintItem) -> ConstraintDescriptionEditable - func equalTo(other: View) -> ConstraintDescriptionEditable - func equalToSuperview() -> ConstraintDescriptionEditable - @available(iOS 7.0, *) - func equalTo(other: LayoutSupport) -> ConstraintDescriptionEditable - @available(iOS 9.0, OSX 10.11, *) - func equalTo(other: NSLayoutAnchor) -> ConstraintDescriptionEditable - func equalTo(other: Float) -> ConstraintDescriptionEditable - func equalTo(other: Double) -> ConstraintDescriptionEditable - func equalTo(other: CGFloat) -> ConstraintDescriptionEditable - func equalTo(other: Int) -> ConstraintDescriptionEditable - func equalTo(other: UInt) -> ConstraintDescriptionEditable - func equalTo(other: CGSize) -> ConstraintDescriptionEditable - func equalTo(other: CGPoint) -> ConstraintDescriptionEditable - func equalTo(other: EdgeInsets) -> ConstraintDescriptionEditable - - func lessThanOrEqualTo(other: ConstraintItem) -> ConstraintDescriptionEditable - func lessThanOrEqualTo(other: View) -> ConstraintDescriptionEditable - func lessThanOrEqualToSuperview() -> ConstraintDescriptionEditable - @available(iOS 7.0, *) - func lessThanOrEqualTo(other: LayoutSupport) -> ConstraintDescriptionEditable - @available(iOS 9.0, OSX 10.11, *) - func lessThanOrEqualTo(other: NSLayoutAnchor) -> ConstraintDescriptionEditable - func lessThanOrEqualTo(other: Float) -> ConstraintDescriptionEditable - func lessThanOrEqualTo(other: Double) -> ConstraintDescriptionEditable - func lessThanOrEqualTo(other: CGFloat) -> ConstraintDescriptionEditable - func lessThanOrEqualTo(other: Int) -> ConstraintDescriptionEditable - func lessThanOrEqualTo(other: UInt) -> ConstraintDescriptionEditable - func lessThanOrEqualTo(other: CGSize) -> ConstraintDescriptionEditable - func lessThanOrEqualTo(other: CGPoint) -> ConstraintDescriptionEditable - func lessThanOrEqualTo(other: EdgeInsets) -> ConstraintDescriptionEditable - - func greaterThanOrEqualTo(other: ConstraintItem) -> ConstraintDescriptionEditable - func greaterThanOrEqualTo(other: View) -> ConstraintDescriptionEditable - func greaterThanOrEqualToSuperview() -> ConstraintDescriptionEditable - @available(iOS 7.0, *) - func greaterThanOrEqualTo(other: LayoutSupport) -> ConstraintDescriptionEditable - @available(iOS 9.0, OSX 10.11, *) - func greaterThanOrEqualTo(other: NSLayoutAnchor) -> ConstraintDescriptionEditable - func greaterThanOrEqualTo(other: Float) -> ConstraintDescriptionEditable - func greaterThanOrEqualTo(other: Double) -> ConstraintDescriptionEditable - func greaterThanOrEqualTo(other: CGFloat) -> ConstraintDescriptionEditable - func greaterThanOrEqualTo(other: Int) -> ConstraintDescriptionEditable - func greaterThanOrEqualTo(other: UInt) -> ConstraintDescriptionEditable - func greaterThanOrEqualTo(other: CGSize) -> ConstraintDescriptionEditable - func greaterThanOrEqualTo(other: CGPoint) -> ConstraintDescriptionEditable - func greaterThanOrEqualTo(other: EdgeInsets) -> ConstraintDescriptionEditable - -} - -/** - Used to expose chaining APIs -*/ -public protocol ConstraintDescriptionExtendable: ConstraintDescriptionRelatable { - - var left: ConstraintDescriptionExtendable { get } - var top: ConstraintDescriptionExtendable { get } - var bottom: ConstraintDescriptionExtendable { get } - var right: ConstraintDescriptionExtendable { get } - var leading: ConstraintDescriptionExtendable { get } - var trailing: ConstraintDescriptionExtendable { get } - var width: ConstraintDescriptionExtendable { get } - var height: ConstraintDescriptionExtendable { get } - var centerX: ConstraintDescriptionExtendable { get } - var centerY: ConstraintDescriptionExtendable { get } - var baseline: ConstraintDescriptionExtendable { get } - - @available(iOS 8.0, *) - var firstBaseline: ConstraintDescriptionExtendable { get } - @available(iOS 8.0, *) - var leftMargin: ConstraintDescriptionExtendable { get } - @available(iOS 8.0, *) - var rightMargin: ConstraintDescriptionExtendable { get } - @available(iOS 8.0, *) - var topMargin: ConstraintDescriptionExtendable { get } - @available(iOS 8.0, *) - var bottomMargin: ConstraintDescriptionExtendable { get } - @available(iOS 8.0, *) - var leadingMargin: ConstraintDescriptionExtendable { get } - @available(iOS 8.0, *) - var trailingMargin: ConstraintDescriptionExtendable { get } - @available(iOS 8.0, *) - var centerXWithinMargins: ConstraintDescriptionExtendable { get } - @available(iOS 8.0, *) - var centerYWithinMargins: ConstraintDescriptionExtendable { get } -} - -/** - Used to internally manage building constraint - */ -internal class ConstraintDescription: ConstraintDescriptionExtendable, ConstraintDescriptionEditable, ConstraintDescriptionFinalizable { - - internal var left: ConstraintDescriptionExtendable { return self.addConstraint(ConstraintAttributes.Left) } - internal var top: ConstraintDescriptionExtendable { return self.addConstraint(ConstraintAttributes.Top) } - internal var right: ConstraintDescriptionExtendable { return self.addConstraint(ConstraintAttributes.Right) } - internal var bottom: ConstraintDescriptionExtendable { return self.addConstraint(ConstraintAttributes.Bottom) } - internal var leading: ConstraintDescriptionExtendable { return self.addConstraint(ConstraintAttributes.Leading) } - internal var trailing: ConstraintDescriptionExtendable { return self.addConstraint(ConstraintAttributes.Trailing) } - internal var width: ConstraintDescriptionExtendable { return self.addConstraint(ConstraintAttributes.Width) } - internal var height: ConstraintDescriptionExtendable { return self.addConstraint(ConstraintAttributes.Height) } - internal var centerX: ConstraintDescriptionExtendable { return self.addConstraint(ConstraintAttributes.CenterX) } - internal var centerY: ConstraintDescriptionExtendable { return self.addConstraint(ConstraintAttributes.CenterY) } - internal var baseline: ConstraintDescriptionExtendable { return self.addConstraint(ConstraintAttributes.Baseline) } - internal var label: String? - - @available(iOS 8.0, *) - internal var firstBaseline: ConstraintDescriptionExtendable { return self.addConstraint(ConstraintAttributes.FirstBaseline) } - @available(iOS 8.0, *) - internal var leftMargin: ConstraintDescriptionExtendable { return self.addConstraint(ConstraintAttributes.LeftMargin) } - @available(iOS 8.0, *) - internal var rightMargin: ConstraintDescriptionExtendable { return self.addConstraint(ConstraintAttributes.RightMargin) } - @available(iOS 8.0, *) - internal var topMargin: ConstraintDescriptionExtendable { return self.addConstraint(ConstraintAttributes.TopMargin) } - @available(iOS 8.0, *) - internal var bottomMargin: ConstraintDescriptionExtendable { return self.addConstraint(ConstraintAttributes.BottomMargin) } - @available(iOS 8.0, *) - internal var leadingMargin: ConstraintDescriptionExtendable { return self.addConstraint(ConstraintAttributes.LeadingMargin) } - @available(iOS 8.0, *) - internal var trailingMargin: ConstraintDescriptionExtendable { return self.addConstraint(ConstraintAttributes.TrailingMargin) } - @available(iOS 8.0, *) - internal var centerXWithinMargins: ConstraintDescriptionExtendable { return self.addConstraint(ConstraintAttributes.CenterXWithinMargins) } - @available(iOS 8.0, *) - internal var centerYWithinMargins: ConstraintDescriptionExtendable { return self.addConstraint(ConstraintAttributes.CenterYWithinMargins) } - - // MARK: initializer - - init(fromItem: ConstraintItem) { - self.fromItem = fromItem - self.toItem = ConstraintItem(object: nil, attributes: ConstraintAttributes.None) - } - - // MARK: equalTo - - internal func equalTo(other: ConstraintItem) -> ConstraintDescriptionEditable { - return self.constrainTo(other, relation: .Equal) - } - internal func equalTo(other: View) -> ConstraintDescriptionEditable { - return self.constrainTo(other, relation: .Equal) - } - internal func equalToSuperview() -> ConstraintDescriptionEditable { - guard let superview = fromItem.view?.superview else { - fatalError("equalToSuperview() requires the view have a superview before being set.") + internal let view: ConstraintView + internal var attributes: ConstraintAttributes + internal var relation: ConstraintRelation? = nil + internal var sourceLocation: (String, UInt)? = nil + internal var label: String? = nil + internal var related: ConstraintItem? = nil + internal var multiplier: ConstraintMultiplierTarget = 1.0 + internal var constant: ConstraintConstantTarget = 0.0 + internal var priority: ConstraintPriorityTarget = 1000.0 + internal lazy var constraint: Constraint? = { + guard let relation = self.relation, + let related = self.related, + let sourceLocation = self.sourceLocation else { + return nil } + let from = ConstraintItem(target: self.view, attributes: self.attributes) - return self.equalTo(superview) - } - @available(iOS 7.0, *) - internal func equalTo(other: LayoutSupport) -> ConstraintDescriptionEditable { - return self.constrainTo(other, relation: .Equal) - } - @available(iOS 9.0, OSX 10.11, *) - internal func equalTo(other: NSLayoutAnchor) -> ConstraintDescriptionEditable { - return self.constrainTo(other, relation: .Equal) - } - internal func equalTo(other: Float) -> ConstraintDescriptionEditable { - return self.constrainTo(other, relation: .Equal) - } - internal func equalTo(other: Double) -> ConstraintDescriptionEditable { - return self.constrainTo(Float(other), relation: .Equal) - } - internal func equalTo(other: CGFloat) -> ConstraintDescriptionEditable { - return self.constrainTo(Float(other), relation: .Equal) - } - internal func equalTo(other: Int) -> ConstraintDescriptionEditable { - return self.constrainTo(Float(other), relation: .Equal) - } - internal func equalTo(other: UInt) -> ConstraintDescriptionEditable { - return self.constrainTo(Float(other), relation: .Equal) - } - internal func equalTo(other: CGSize) -> ConstraintDescriptionEditable { - return self.constrainTo(other, relation: .Equal) - } - internal func equalTo(other: CGPoint) -> ConstraintDescriptionEditable { - return self.constrainTo(other, relation: .Equal) - } - internal func equalTo(other: EdgeInsets) -> ConstraintDescriptionEditable { - return self.constrainTo(other, relation: .Equal) + return Constraint( + from: from, + to: related, + relation: relation, + sourceLocation: sourceLocation, + label: self.label, + multiplier: self.multiplier, + constant: self.constant, + priority: self.priority + ) + }() + + // MARK: Initialization + + internal init(view: ConstraintView, attributes: ConstraintAttributes) { + self.view = view + self.attributes = attributes } - // MARK: lessThanOrEqualTo - - internal func lessThanOrEqualTo(other: ConstraintItem) -> ConstraintDescriptionEditable { - return self.constrainTo(other, relation: .LessThanOrEqualTo) - } - internal func lessThanOrEqualTo(other: View) -> ConstraintDescriptionEditable { - return self.constrainTo(other, relation: .LessThanOrEqualTo) - } - internal func lessThanOrEqualToSuperview() -> ConstraintDescriptionEditable { - guard let superview = fromItem.view?.superview else { - fatalError("lessThanOrEqualToSuperview() requires the view have a superview before being set.") - } - - return self.lessThanOrEqualTo(superview) - } - @available(iOS 7.0, *) - internal func lessThanOrEqualTo(other: LayoutSupport) -> ConstraintDescriptionEditable { - return self.constrainTo(other, relation: .LessThanOrEqualTo) - } - @available(iOS 9.0, OSX 10.11, *) - internal func lessThanOrEqualTo(other: NSLayoutAnchor) -> ConstraintDescriptionEditable { - return self.constrainTo(other, relation: .LessThanOrEqualTo) - } - internal func lessThanOrEqualTo(other: Float) -> ConstraintDescriptionEditable { - return self.constrainTo(other, relation: .LessThanOrEqualTo) - } - internal func lessThanOrEqualTo(other: Double) -> ConstraintDescriptionEditable { - return self.constrainTo(Float(other), relation: .LessThanOrEqualTo) - } - internal func lessThanOrEqualTo(other: CGFloat) -> ConstraintDescriptionEditable { - return self.constrainTo(Float(other), relation: .LessThanOrEqualTo) - } - internal func lessThanOrEqualTo(other: Int) -> ConstraintDescriptionEditable { - return self.constrainTo(Float(other), relation: .LessThanOrEqualTo) - } - internal func lessThanOrEqualTo(other: UInt) -> ConstraintDescriptionEditable { - return self.constrainTo(Float(other), relation: .LessThanOrEqualTo) - } - internal func lessThanOrEqualTo(other: CGSize) -> ConstraintDescriptionEditable { - return self.constrainTo(other, relation: .LessThanOrEqualTo) - } - internal func lessThanOrEqualTo(other: CGPoint) -> ConstraintDescriptionEditable { - return self.constrainTo(other, relation: .LessThanOrEqualTo) - } - internal func lessThanOrEqualTo(other: EdgeInsets) -> ConstraintDescriptionEditable { - return self.constrainTo(other, relation: .LessThanOrEqualTo) - } - - // MARK: greaterThanOrEqualTo - - internal func greaterThanOrEqualTo(other: ConstraintItem) -> ConstraintDescriptionEditable { - return self.constrainTo(other, relation: .GreaterThanOrEqualTo) - } - internal func greaterThanOrEqualTo(other: View) -> ConstraintDescriptionEditable { - return self.constrainTo(other, relation: .GreaterThanOrEqualTo) - } - internal func greaterThanOrEqualToSuperview() -> ConstraintDescriptionEditable { - guard let superview = fromItem.view?.superview else { - fatalError("greaterThanOrEqualToSuperview() requires the view have a superview before being set.") - } - - return self.greaterThanOrEqualTo(superview) - } - @available(iOS 7.0, *) - internal func greaterThanOrEqualTo(other: LayoutSupport) -> ConstraintDescriptionEditable { - return self.constrainTo(other, relation: .GreaterThanOrEqualTo) - } - @available(iOS 9.0, OSX 10.11, *) - internal func greaterThanOrEqualTo(other: NSLayoutAnchor) -> ConstraintDescriptionEditable { - return self.constrainTo(other, relation: .LessThanOrEqualTo) - } - internal func greaterThanOrEqualTo(other: Float) -> ConstraintDescriptionEditable { - return self.constrainTo(other, relation: .GreaterThanOrEqualTo) - } - internal func greaterThanOrEqualTo(other: Double) -> ConstraintDescriptionEditable { - return self.constrainTo(Float(other), relation: .GreaterThanOrEqualTo) - } - internal func greaterThanOrEqualTo(other: CGFloat) -> ConstraintDescriptionEditable { - return self.constrainTo(Float(other), relation: .GreaterThanOrEqualTo) - } - internal func greaterThanOrEqualTo(other: Int) -> ConstraintDescriptionEditable { - return self.constrainTo(Float(other), relation: .GreaterThanOrEqualTo) - } - internal func greaterThanOrEqualTo(other: UInt) -> ConstraintDescriptionEditable { - return self.constrainTo(Float(other), relation: .GreaterThanOrEqualTo) - } - internal func greaterThanOrEqualTo(other: CGSize) -> ConstraintDescriptionEditable { - return self.constrainTo(other, relation: .GreaterThanOrEqualTo) - } - internal func greaterThanOrEqualTo(other: CGPoint) -> ConstraintDescriptionEditable { - return self.constrainTo(other, relation: .GreaterThanOrEqualTo) - } - internal func greaterThanOrEqualTo(other: EdgeInsets) -> ConstraintDescriptionEditable { - return self.constrainTo(other, relation: .GreaterThanOrEqualTo) - } - - // MARK: multiplier - - internal func multipliedBy(amount: Float) -> ConstraintDescriptionEditable { - self.multiplier = amount - return self - } - internal func multipliedBy(amount: Double) -> ConstraintDescriptionEditable { - return self.multipliedBy(Float(amount)) - } - internal func multipliedBy(amount: CGFloat) -> ConstraintDescriptionEditable { - return self.multipliedBy(Float(amount)) - } - internal func multipliedBy(amount: Int) -> ConstraintDescriptionEditable { - return self.multipliedBy(Float(amount)) - } - internal func multipliedBy(amount: UInt) -> ConstraintDescriptionEditable { - return self.multipliedBy(Float(amount)) - } - - internal func dividedBy(amount: Float) -> ConstraintDescriptionEditable { - self.multiplier = 1.0 / amount; - return self - } - internal func dividedBy(amount: Double) -> ConstraintDescriptionEditable { - return self.dividedBy(Float(amount)) - } - internal func dividedBy(amount: CGFloat) -> ConstraintDescriptionEditable { - return self.dividedBy(Float(amount)) - } - internal func dividedBy(amount: Int) -> ConstraintDescriptionEditable { - return self.dividedBy(Float(amount)) - } - internal func dividedBy(amount: UInt) -> ConstraintDescriptionEditable { - return self.dividedBy(Float(amount)) - } - - // MARK: offset - - internal func offset(amount: Float) -> ConstraintDescriptionEditable { - self.constant = amount - return self - } - internal func offset(amount: Double) -> ConstraintDescriptionEditable { - return self.offset(Float(amount)) - } - internal func offset(amount: CGFloat) -> ConstraintDescriptionEditable { - return self.offset(Float(amount)) - } - internal func offset(amount: Int) -> ConstraintDescriptionEditable { - return self.offset(Float(amount)) - } - internal func offset(amount: UInt) -> ConstraintDescriptionEditable { - return self.offset(Float(amount)) - } - internal func offset(amount: CGPoint) -> ConstraintDescriptionEditable { - self.constant = amount - return self - } - internal func offset(amount: CGSize) -> ConstraintDescriptionEditable { - self.constant = amount - return self - } - internal func offset(amount: EdgeInsets) -> ConstraintDescriptionEditable { - self.constant = amount - return self - } - - // MARK: inset - - internal func inset(amount: Float) -> ConstraintDescriptionEditable { - let value = CGFloat(amount) - self.constant = EdgeInsets(top: value, left: value, bottom: -value, right: -value) - return self - } - internal func inset(amount: Double) -> ConstraintDescriptionEditable { - let value = CGFloat(amount) - self.constant = EdgeInsets(top: value, left: value, bottom: -value, right: -value) - return self - } - internal func inset(amount: CGFloat) -> ConstraintDescriptionEditable { - self.constant = EdgeInsets(top: amount, left: amount, bottom: -amount, right: -amount) - return self - } - internal func inset(amount: Int) -> ConstraintDescriptionEditable { - let value = CGFloat(amount) - self.constant = EdgeInsets(top: value, left: value, bottom: -value, right: -value) - return self - } - internal func inset(amount: UInt) -> ConstraintDescriptionEditable { - let value = CGFloat(amount) - self.constant = EdgeInsets(top: value, left: value, bottom: -value, right: -value) - return self - } - internal func inset(amount: EdgeInsets) -> ConstraintDescriptionEditable { - self.constant = EdgeInsets(top: amount.top, left: amount.left, bottom: -amount.bottom, right: -amount.right) - return self - } - - // MARK: priority - - internal func priority(priority: Float) -> ConstraintDescriptionFinalizable { - self.priority = priority - return self - } - internal func priority(priority: Double) -> ConstraintDescriptionFinalizable { - return self.priority(Float(priority)) - } - internal func priority(priority: CGFloat) -> ConstraintDescriptionFinalizable { - return self.priority(Float(priority)) - } - func priority(priority: UInt) -> ConstraintDescriptionFinalizable { - return self.priority(Float(priority)) - } - internal func priority(priority: Int) -> ConstraintDescriptionFinalizable { - return self.priority(Float(priority)) - } - internal func priorityRequired() -> ConstraintDescriptionFinalizable { - return self.priority(1000.0) - } - internal func priorityHigh() -> ConstraintDescriptionFinalizable { - return self.priority(750.0) - } - internal func priorityMedium() -> ConstraintDescriptionFinalizable { - #if os(iOS) || os(tvOS) - return self.priority(500.0) - #else - return self.priority(501.0) - #endif - } - internal func priorityLow() -> ConstraintDescriptionFinalizable { - return self.priority(250.0) - } - - // MARK: Constraint - - internal var constraint: Constraint { - if self.concreteConstraint == nil { - if self.relation == nil { - fatalError("Attempting to create a constraint from a ConstraintDescription before it has been fully chained.") - } - self.concreteConstraint = ConcreteConstraint( - fromItem: self.fromItem, - toItem: self.toItem, - relation: self.relation!, - constant: self.constant, - multiplier: self.multiplier, - priority: self.priority, - label: self.label) - } - return self.concreteConstraint! - } - - func labeled(label: String) -> ConstraintDescriptionFinalizable { - self.label = label - return self - } - - // MARK: Private - - private let fromItem: ConstraintItem - private var toItem: ConstraintItem { - willSet { - if self.concreteConstraint != nil { - fatalError("Attempting to modify a ConstraintDescription after its constraint has been created.") - } - } - } - private var relation: ConstraintRelation? { - willSet { - if self.concreteConstraint != nil { - fatalError("Attempting to modify a ConstraintDescription after its constraint has been created.") - } - } - } - private var constant: Any = Float(0.0) { - willSet { - if self.concreteConstraint != nil { - fatalError("Attempting to modify a ConstraintDescription after its constraint has been created.") - } - } - } - private var multiplier: Float = 1.0 { - willSet { - if self.concreteConstraint != nil { - fatalError("Attempting to modify a ConstraintDescription after its constraint has been created.") - } - } - } - private var priority: Float = 1000.0 { - willSet { - if self.concreteConstraint != nil { - fatalError("Attempting to modify a ConstraintDescription after its constraint has been created.") - } - } - } - private var concreteConstraint: ConcreteConstraint? = nil - - private func addConstraint(attributes: ConstraintAttributes) -> ConstraintDescription { - if self.relation == nil { - self.fromItem.attributes += attributes - } - return self - } - - private func constrainTo(other: ConstraintItem, relation: ConstraintRelation) -> ConstraintDescription { - if other.attributes != ConstraintAttributes.None { - let toLayoutAttributes = other.attributes.layoutAttributes - if toLayoutAttributes.count > 1 { - let fromLayoutAttributes = self.fromItem.attributes.layoutAttributes - if toLayoutAttributes != fromLayoutAttributes { - NSException(name: "Invalid Constraint", reason: "Cannot constrain to multiple non identical attributes", userInfo: nil).raise() - return self - } - other.attributes = ConstraintAttributes.None - } - } - self.toItem = other - self.relation = relation - return self - } - - private func constrainTo(other: View, relation: ConstraintRelation) -> ConstraintDescription { - return constrainTo(ConstraintItem(object: other, attributes: ConstraintAttributes.None), relation: relation) - } - - @available(iOS 7.0, *) - private func constrainTo(other: LayoutSupport, relation: ConstraintRelation) -> ConstraintDescription { - return constrainTo(ConstraintItem(object: other, attributes: ConstraintAttributes.None), relation: relation) - } - - @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) - } - - private func constrainTo(other: Float, relation: ConstraintRelation) -> ConstraintDescription { - self.constant = other - return constrainTo(ConstraintItem(object: nil, attributes: ConstraintAttributes.None), relation: relation) - } - - private func constrainTo(other: Double, relation: ConstraintRelation) -> ConstraintDescription { - self.constant = other - return constrainTo(ConstraintItem(object: nil, attributes: ConstraintAttributes.None), relation: relation) - } - - private func constrainTo(other: CGSize, relation: ConstraintRelation) -> ConstraintDescription { - self.constant = other - return constrainTo(ConstraintItem(object: nil, attributes: ConstraintAttributes.None), relation: relation) - } - - private func constrainTo(other: CGPoint, relation: ConstraintRelation) -> ConstraintDescription { - self.constant = other - return constrainTo(ConstraintItem(object: nil, attributes: ConstraintAttributes.None), relation: relation) - } - - private func constrainTo(other: EdgeInsets, relation: ConstraintRelation) -> ConstraintDescription { - self.constant = other - return constrainTo(ConstraintItem(object: nil, attributes: ConstraintAttributes.None), relation: relation) - } } diff --git a/Source/ConstraintInsetTarget.swift b/Source/ConstraintInsetTarget.swift new file mode 100644 index 0000000..ba8a0f3 --- /dev/null +++ b/Source/ConstraintInsetTarget.swift @@ -0,0 +1,72 @@ +// +// 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 protocol ConstraintInsetTarget: ConstraintConstantTarget { +} + +extension Int: ConstraintInsetTarget { +} + +extension UInt: ConstraintInsetTarget { +} + +extension Float: ConstraintInsetTarget { +} + +extension Double: ConstraintInsetTarget { +} + +extension CGFloat: ConstraintInsetTarget { +} + +extension ConstraintInsets: ConstraintInsetTarget { +} + +extension ConstraintInsetTarget { + + internal var constraintInsetTargetValue: ConstraintInsets { + if let amount = self as? ConstraintInsets { + return amount + } else if let amount = self as? Float { + return ConstraintInsets(top: CGFloat(amount), left: CGFloat(amount), bottom: CGFloat(amount), right: CGFloat(amount)) + } else if let amount = self as? Double { + return ConstraintInsets(top: CGFloat(amount), left: CGFloat(amount), bottom: CGFloat(amount), right: CGFloat(amount)) + } else if let amount = self as? CGFloat { + return ConstraintInsets(top: amount, left: amount, bottom: amount, right: amount) + } else if let amount = self as? Int { + return ConstraintInsets(top: CGFloat(amount), left: CGFloat(amount), bottom: CGFloat(amount), right: CGFloat(amount)) + } else if let amount = self as? UInt { + return ConstraintInsets(top: CGFloat(amount), left: CGFloat(amount), bottom: CGFloat(amount), right: CGFloat(amount)) + } else { + return ConstraintInsets(top: 0, left: 0, bottom: 0, right: 0) + } + } + +} diff --git a/Source/ConstraintInsets.swift b/Source/ConstraintInsets.swift new file mode 100644 index 0000000..6ecac6b --- /dev/null +++ b/Source/ConstraintInsets.swift @@ -0,0 +1,35 @@ +// +// 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 + + +#if os(iOS) || os(tvOS) + public typealias ConstraintInsets = UIEdgeInsets +#else + public typealias ConstraintInsets = EdgeInsets +#endif diff --git a/Source/ConstraintItem.swift b/Source/ConstraintItem.swift index b2c9062..a9477da 100644 --- a/Source/ConstraintItem.swift +++ b/Source/ConstraintItem.swift @@ -1,7 +1,7 @@ // // SnapKit // -// Copyright (c) 2011-2015 SnapKit Team - https://github.com/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 @@ -22,47 +22,40 @@ // THE SOFTWARE. #if os(iOS) || os(tvOS) -import UIKit + import UIKit #else -import AppKit + import AppKit #endif -/** - Used to assist in building a constraint -*/ -public class ConstraintItem { + +public class ConstraintItem: Equatable { - internal init(object: AnyObject?, attributes: ConstraintAttributes) { - self.object = object + internal weak var target: AnyObject? + internal let attributes: ConstraintAttributes + + internal init(target: AnyObject?, attributes: ConstraintAttributes) { + self.target = target self.attributes = attributes } - internal weak var object: AnyObject? - internal var attributes: ConstraintAttributes - - internal var view: View? { - return self.object as? View + internal var view: ConstraintView? { + return self.target as? ConstraintView } - @available(iOS 7.0, *) - internal var layoutSupport: LayoutSupport? { - return self.object as? LayoutSupport - } } - -internal func ==(left: ConstraintItem, right: ConstraintItem) -> Bool { - if left.object == nil { - return false +public func ==(lhs: ConstraintItem, rhs: ConstraintItem) -> Bool { + // pointer equality + guard lhs !== rhs else { + return true } - if right.object == nil { - return false - } - if left.object !== right.object { - return false - } - if left.attributes != right.attributes { - return false + + // must both have valid targets and identical attributes + guard let target1 = lhs.target, + let target2 = rhs.target, + target1 === target2 && lhs.attributes == rhs.attributes else { + return false } + return true -} \ No newline at end of file +} diff --git a/Source/ConstraintLayoutGuide.swift b/Source/ConstraintLayoutGuide.swift new file mode 100644 index 0000000..f6eba82 --- /dev/null +++ b/Source/ConstraintLayoutGuide.swift @@ -0,0 +1,36 @@ +// +// 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 + + +#if os(iOS) || os(tvOS) + @available(iOS 9.0, *) + public typealias ConstraintLayoutGuide = UILayoutGuide +#else + public class ConstraintLayoutGuide {} +#endif diff --git a/Source/ConstraintLayoutGuideDSL.swift b/Source/ConstraintLayoutGuideDSL.swift new file mode 100644 index 0000000..62bd9b4 --- /dev/null +++ b/Source/ConstraintLayoutGuideDSL.swift @@ -0,0 +1,45 @@ +// +// 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 + + +@available(iOS 9.0, *) +public struct ConstraintLayoutGuideDSL: ConstraintAttributesDSL { + + public var target: AnyObject? { + return self.guide + } + + internal let guide: ConstraintLayoutGuide + + internal init(guide: ConstraintLayoutGuide) { + self.guide = guide + + } + +} diff --git a/Source/ConstraintLayoutSupport.swift b/Source/ConstraintLayoutSupport.swift new file mode 100644 index 0000000..e92e9fb --- /dev/null +++ b/Source/ConstraintLayoutSupport.swift @@ -0,0 +1,36 @@ +// +// 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 + + +#if os(iOS) || os(tvOS) + @available(iOS 8.0, *) + public typealias ConstraintLayoutSupport = UILayoutSupport +#else + public class ConstraintLayoutSupport {} +#endif diff --git a/Source/ViewController+SnapKit.swift b/Source/ConstraintLayoutSupportDSL.swift similarity index 56% rename from Source/ViewController+SnapKit.swift rename to Source/ConstraintLayoutSupportDSL.swift index ed5451b..5d6ae89 100644 --- a/Source/ViewController+SnapKit.swift +++ b/Source/ConstraintLayoutSupportDSL.swift @@ -1,7 +1,7 @@ // // SnapKit // -// Copyright (c) 2011-2015 SnapKit Team - https://github.com/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 @@ -22,24 +22,35 @@ // THE SOFTWARE. #if os(iOS) || os(tvOS) -import UIKit - -/** - Used to expose public API on view controllers -*/ -public extension UIViewController { - - /// top layout guide top - public var snp_topLayoutGuideTop: ConstraintItem { return ConstraintItem(object: self.topLayoutGuide, attributes: ConstraintAttributes.Top) } - - /// top layout guide bottom - public var snp_topLayoutGuideBottom: ConstraintItem { return ConstraintItem(object: self.topLayoutGuide, attributes: ConstraintAttributes.Bottom) } - - /// bottom layout guide top - public var snp_bottomLayoutGuideTop: ConstraintItem { return ConstraintItem(object: self.bottomLayoutGuide, attributes: ConstraintAttributes.Top) } - - /// bottom layout guide bottom - public var snp_bottomLayoutGuideBottom: ConstraintItem { return ConstraintItem(object: self.bottomLayoutGuide, attributes: ConstraintAttributes.Bottom) } - -} + import UIKit +#else + import AppKit #endif + + +@available(iOS 8.0, *) +public struct ConstraintLayoutSupportDSL: ConstraintDSL { + + public var target: AnyObject? { + return self.support + } + + internal let support: ConstraintLayoutSupport + + internal init(support: ConstraintLayoutSupport) { + self.support = support + + } + + public var top: ConstraintItem { + return ConstraintItem(target: self.target, attributes: ConstraintAttributes.top) + } + + public var bottom: ConstraintItem { + return ConstraintItem(target: self.target, attributes: ConstraintAttributes.bottom) + } + + public var height: ConstraintItem { + return ConstraintItem(target: self.target, attributes: ConstraintAttributes.height) + } +} diff --git a/Source/ConstraintMaker.swift b/Source/ConstraintMaker.swift index 154b9dd..0ea2dd2 100644 --- a/Source/ConstraintMaker.swift +++ b/Source/ConstraintMaker.swift @@ -1,7 +1,7 @@ // // SnapKit // -// Copyright (c) 2011-2015 SnapKit Team - https://github.com/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 @@ -22,175 +22,185 @@ // THE SOFTWARE. #if os(iOS) || os(tvOS) -import UIKit + import UIKit #else -import AppKit + import AppKit #endif -/** - Used to make constraints -*/ public class ConstraintMaker { - /// left edge - public var left: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.Left) } + public var left: ConstraintMakerExtendable { + return self.makeExtendableWithAttributes(.left) + } - /// top edge - public var top: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.Top) } + public var top: ConstraintMakerExtendable { + return self.makeExtendableWithAttributes(.top) + } - /// right edge - public var right: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.Right) } + public var bottom: ConstraintMakerExtendable { + return self.makeExtendableWithAttributes(.bottom) + } - /// bottom edge - public var bottom: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.Bottom) } + public var right: ConstraintMakerExtendable { + return self.makeExtendableWithAttributes(.right) + } - /// leading edge - public var leading: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.Leading) } + public var leading: ConstraintMakerExtendable { + return self.makeExtendableWithAttributes(.leading) + } - /// trailing edge - public var trailing: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.Trailing) } + public var trailing: ConstraintMakerExtendable { + return self.makeExtendableWithAttributes(.trailing) + } - /// width dimension - public var width: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.Width) } + public var width: ConstraintMakerExtendable { + return self.makeExtendableWithAttributes(.width) + } - /// height dimension - public var height: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.Height) } + public var height: ConstraintMakerExtendable { + return self.makeExtendableWithAttributes(.height) + } - /// centerX dimension - public var centerX: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.CenterX) } + public var centerX: ConstraintMakerExtendable { + return self.makeExtendableWithAttributes(.centerX) + } - /// centerY dimension - public var centerY: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.CenterY) } + public var centerY: ConstraintMakerExtendable { + return self.makeExtendableWithAttributes(.centerY) + } - /// baseline position - public var baseline: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.Baseline) } + @available(*, deprecated:0.40.0, message:"Use lastBaseline instead") + public var baseline: ConstraintMakerExtendable { + return self.makeExtendableWithAttributes(.lastBaseline) + } + + public var lastBaseline: ConstraintMakerExtendable { + return self.makeExtendableWithAttributes(.lastBaseline) + } + + @available(iOS 8.0, OSX 10.11, *) + public var firstBaseline: ConstraintMakerExtendable { + return self.makeExtendableWithAttributes(.firstBaseline) + } - /// firse baseline position @available(iOS 8.0, *) - public var firstBaseline: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.FirstBaseline) } + public var leftMargin: ConstraintMakerExtendable { + return self.makeExtendableWithAttributes(.leftMargin) + } - /// left margin @available(iOS 8.0, *) - public var leftMargin: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.LeftMargin) } + public var rightMargin: ConstraintMakerExtendable { + return self.makeExtendableWithAttributes(.rightMargin) + } - /// right margin @available(iOS 8.0, *) - public var rightMargin: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.RightMargin) } + public var bottomMargin: ConstraintMakerExtendable { + return self.makeExtendableWithAttributes(.bottomMargin) + } - /// top margin @available(iOS 8.0, *) - public var topMargin: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.TopMargin) } + public var leadingMargin: ConstraintMakerExtendable { + return self.makeExtendableWithAttributes(.leadingMargin) + } - /// bottom margin @available(iOS 8.0, *) - public var bottomMargin: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.BottomMargin) } + public var trailingMargin: ConstraintMakerExtendable { + return self.makeExtendableWithAttributes(.trailingMargin) + } - /// leading margin @available(iOS 8.0, *) - public var leadingMargin: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.LeadingMargin) } + public var centerXWithinMargins: ConstraintMakerExtendable { + return self.makeExtendableWithAttributes(.centerXWithinMargins) + } - /// trailing margin @available(iOS 8.0, *) - public var trailingMargin: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.TrailingMargin) } + public var centerYWithinMargins: ConstraintMakerExtendable { + return self.makeExtendableWithAttributes(.centerYWithinMargins) + } + + public var edges: ConstraintMakerExtendable { + return self.makeExtendableWithAttributes(.edges) + } + public var size: ConstraintMakerExtendable { + return self.makeExtendableWithAttributes(.size) + } + public var center: ConstraintMakerExtendable { + return self.makeExtendableWithAttributes(.center) + } - /// centerX within margins @available(iOS 8.0, *) - public var centerXWithinMargins: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.CenterXWithinMargins) } + public var margins: ConstraintMakerExtendable { + return self.makeExtendableWithAttributes(.margins) + } - /// centerY within margins @available(iOS 8.0, *) - public var centerYWithinMargins: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.CenterYWithinMargins) } + public var centerWithinMargins: ConstraintMakerExtendable { + return self.makeExtendableWithAttributes(.centerWithinMargins) + } - /// top + left + bottom + right edges - public var edges: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.Edges) } + private let view: ConstraintView + private var descriptions = [ConstraintDescription]() - /// width + height dimensions - public var size: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.Size) } - - // centerX + centerY positions - public var center: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.Center) } - - // top + left + bottom + right margins - @available(iOS 8.0, *) - public var margins: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.Margins) } - - // centerX + centerY within margins - @available(iOS 8.0, *) - public var centerWithinMargins: ConstraintDescriptionExtendable { return self.makeConstraintDescription(ConstraintAttributes.CenterWithinMargins) } - - internal init(view: View, file: String, line: UInt) { + internal init(view: ConstraintView) { self.view = view - self.file = file - self.line = line + self.view.translatesAutoresizingMaskIntoConstraints = false } - internal let file: String - internal let line: UInt - internal let view: View - internal var constraintDescriptions = [ConstraintDescription]() - - internal func makeConstraintDescription(attributes: ConstraintAttributes) -> ConstraintDescription { - let item = ConstraintItem(object: self.view, attributes: attributes) - let constraintDescription = ConstraintDescription(fromItem: item) - self.constraintDescriptions.append(constraintDescription) - return constraintDescription + internal func makeExtendableWithAttributes(_ attributes: ConstraintAttributes) -> ConstraintMakerExtendable { + let description = ConstraintDescription(view: self.view, attributes: attributes) + self.descriptions.append(description) + return ConstraintMakerExtendable(description) } - internal class func prepareConstraints(view view: View, file: String = "Unknown", line: UInt = 0, @noescape closure: (make: ConstraintMaker) -> Void) -> [Constraint] { - let maker = ConstraintMaker(view: view, file: file, line: line) - closure(make: maker) - - let constraints = maker.constraintDescriptions.map { $0.constraint } - for constraint in constraints { - constraint.makerFile = maker.file - constraint.makerLine = maker.line - } + internal static func prepareConstraints(view: ConstraintView, closure: (_ make: ConstraintMaker) -> Void) -> [Constraint] { + let maker = ConstraintMaker(view: view) + closure(maker) + let constraints = maker.descriptions + .map { $0.constraint } + .filter { $0 != nil } + .map { $0! } return constraints } - internal class func makeConstraints(view view: View, file: String = "Unknown", line: UInt = 0, @noescape closure: (make: ConstraintMaker) -> Void) { - view.translatesAutoresizingMaskIntoConstraints = false - let maker = ConstraintMaker(view: view, file: file, line: line) - closure(make: maker) - - let constraints = maker.constraintDescriptions.map { $0.constraint as! ConcreteConstraint } + internal static func makeConstraints(view: ConstraintView, closure: (_ make: ConstraintMaker) -> Void) { + let maker = ConstraintMaker(view: view) + closure(maker) + let constraints = maker.descriptions + .map { $0.constraint } + .filter { $0 != nil } + .map { $0! } for constraint in constraints { - constraint.makerFile = maker.file - constraint.makerLine = maker.line - constraint.installOnView(updateExisting: false) + constraint.activateIfNeeded(updatingExisting: false) } } - internal class func remakeConstraints(view view: View, file: String = "Unknown", line: UInt = 0, @noescape closure: (make: ConstraintMaker) -> Void) { - view.translatesAutoresizingMaskIntoConstraints = false - let maker = ConstraintMaker(view: view, file: file, line: line) - closure(make: maker) - + internal static func remakeConstraints(view: ConstraintView, closure: (_ make: ConstraintMaker) -> Void) { self.removeConstraints(view: view) - let constraints = maker.constraintDescriptions.map { $0.constraint as! ConcreteConstraint } - for constraint in constraints { - constraint.makerFile = maker.file - constraint.makerLine = maker.line - constraint.installOnView(updateExisting: false) - } + self.makeConstraints(view: view, closure: closure) } - internal class func updateConstraints(view view: View, file: String = "Unknown", line: UInt = 0, @noescape closure: (make: ConstraintMaker) -> Void) { - view.translatesAutoresizingMaskIntoConstraints = false - let maker = ConstraintMaker(view: view, file: file, line: line) - closure(make: maker) + internal static func updateConstraints(view: ConstraintView, closure: (_ make: ConstraintMaker) -> Void) { + guard view.snp.layoutConstraints.count > 0 else { + self.makeConstraints(view: view, closure: closure) + return + } - let constraints = maker.constraintDescriptions.map { $0.constraint as! ConcreteConstraint} + let maker = ConstraintMaker(view: view) + closure(maker) + let constraints = maker.descriptions + .map { $0.constraint } + .filter { $0 != nil } + .map { $0! } for constraint in constraints { - constraint.makerFile = maker.file - constraint.makerLine = maker.line - constraint.installOnView(updateExisting: true) + constraint.activateIfNeeded(updatingExisting: true) } } - internal class func removeConstraints(view view: View) { - for existingLayoutConstraint in view.snp_installedLayoutConstraints { - existingLayoutConstraint.snp_constraint?.uninstall() + internal static func removeConstraints(view: ConstraintView) { + let constraints = view.snp.layoutConstraints.map { $0.constraint! } + for constraint in constraints { + constraint.deactivateIfNeeded() } } + } diff --git a/Source/ConstraintMakerEditable.swift b/Source/ConstraintMakerEditable.swift new file mode 100644 index 0000000..fb88c41 --- /dev/null +++ b/Source/ConstraintMakerEditable.swift @@ -0,0 +1,56 @@ +// +// 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 class ConstraintMakerEditable: ConstraintMakerPriortizable { + + @discardableResult + public func multipliedBy(_ amount: ConstraintMultiplierTarget) -> ConstraintMakerEditable { + self.description.multiplier = amount + return self + } + + @discardableResult + public func dividedBy(_ amount: ConstraintMultiplierTarget) -> ConstraintMakerEditable { + return self.multipliedBy(1.0 / amount.constraintMultiplierTargetValue) + } + + @discardableResult + public func offset(_ amount: ConstraintOffsetTarget) -> ConstraintMakerEditable { + self.description.constant = amount.constraintOffsetTargetValue + return self + } + + @discardableResult + public func inset(_ amount: ConstraintInsetTarget) -> ConstraintMakerEditable { + self.description.constant = amount.constraintInsetTargetValue + return self + } + +} diff --git a/Source/ConstraintMakerExtendable.swift b/Source/ConstraintMakerExtendable.swift new file mode 100644 index 0000000..2a57da9 --- /dev/null +++ b/Source/ConstraintMakerExtendable.swift @@ -0,0 +1,163 @@ +// +// 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 class ConstraintMakerExtendable: ConstraintMakerRelatable { + + public var left: ConstraintMakerExtendable { + self.description.attributes += .left + return self + } + + public var top: ConstraintMakerExtendable { + self.description.attributes += .top + return self + } + + public var bottom: ConstraintMakerExtendable { + self.description.attributes += .bottom + return self + } + + public var right: ConstraintMakerExtendable { + self.description.attributes += .right + return self + } + + public var leading: ConstraintMakerExtendable { + self.description.attributes += .leading + return self + } + + public var trailing: ConstraintMakerExtendable { + self.description.attributes += .trailing + return self + } + + public var width: ConstraintMakerExtendable { + self.description.attributes += .width + return self + } + + public var height: ConstraintMakerExtendable { + self.description.attributes += .height + return self + } + + public var centerX: ConstraintMakerExtendable { + self.description.attributes += .centerX + return self + } + + public var centerY: ConstraintMakerExtendable { + self.description.attributes += .centerY + return self + } + + @available(*, deprecated:0.40.0, message:"Use lastBaseline instead") + public var baseline: ConstraintMakerExtendable { + self.description.attributes += .lastBaseline + return self + } + + public var lastBaseline: ConstraintMakerExtendable { + self.description.attributes += .lastBaseline + return self + } + + @available(iOS 8.0, OSX 10.11, *) + public var firstBaseline: ConstraintMakerExtendable { + self.description.attributes += .firstBaseline + return self + } + + @available(iOS 8.0, *) + public var leftMargin: ConstraintMakerExtendable { + self.description.attributes += .leftMargin + return self + } + + @available(iOS 8.0, *) + public var rightMargin: ConstraintMakerExtendable { + self.description.attributes += .rightMargin + return self + } + + @available(iOS 8.0, *) + public var bottomMargin: ConstraintMakerExtendable { + self.description.attributes += .bottomMargin + return self + } + + @available(iOS 8.0, *) + public var leadingMargin: ConstraintMakerExtendable { + self.description.attributes += .leadingMargin + return self + } + + @available(iOS 8.0, *) + public var trailingMargin: ConstraintMakerExtendable { + self.description.attributes += .trailingMargin + return self + } + + @available(iOS 8.0, *) + public var centerXWithinMargins: ConstraintMakerExtendable { + self.description.attributes += .centerXWithinMargins + return self + } + + @available(iOS 8.0, *) + public var centerYWithinMargins: ConstraintMakerExtendable { + self.description.attributes += .centerYWithinMargins + return self + } + + public var edges: ConstraintMakerExtendable { + self.description.attributes += .edges + return self + } + public var size: ConstraintMakerExtendable { + self.description.attributes += .size + return self + } + + @available(iOS 8.0, *) + public var margins: ConstraintMakerExtendable { + self.description.attributes += .margins + return self + } + + @available(iOS 8.0, *) + public var centerWithinMargins: ConstraintMakerExtendable { + self.description.attributes += .centerWithinMargins + return self + } + +} diff --git a/Source/ConstraintMakerFinalizable.swift b/Source/ConstraintMakerFinalizable.swift new file mode 100644 index 0000000..4e1379e --- /dev/null +++ b/Source/ConstraintMakerFinalizable.swift @@ -0,0 +1,49 @@ +// +// 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 class ConstraintMakerFinalizable { + + internal let description: ConstraintDescription + + internal init(_ description: ConstraintDescription) { + self.description = description + } + + @discardableResult + public func labeled(_ label: String) -> ConstraintMakerFinalizable { + self.description.label = label + return self + } + + public var constraint: Constraint { + return self.description.constraint! + } + +} diff --git a/Source/ConstraintMakerPriortizable.swift b/Source/ConstraintMakerPriortizable.swift new file mode 100644 index 0000000..c5fe11a --- /dev/null +++ b/Source/ConstraintMakerPriortizable.swift @@ -0,0 +1,67 @@ +// +// 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 class ConstraintMakerPriortizable: ConstraintMakerFinalizable { + + @discardableResult + public func priority(_ amount: ConstraintPriorityTarget) -> ConstraintMakerFinalizable { + self.description.priority = amount + return self + } + + @available(*, deprecated:0.40.0, message:"Use priority(_ amount: ConstraintPriorityTarget) instead.") + @discardableResult + public func priorityRequired() -> ConstraintMakerFinalizable { + return self.priority(1000) + } + + @available(*, deprecated:0.40.0, message:"Use priority(_ amount: ConstraintPriorityTarget) instead.") + @discardableResult + public func priorityHigh() -> ConstraintMakerFinalizable { + return self.priority(750) + } + + @available(*, deprecated:0.40.0, message:"Use priority(_ amount: ConstraintPriorityTarget) instead.") + @discardableResult + public func priorityMedium() -> ConstraintMakerFinalizable { + #if os(iOS) || os(tvOS) + return self.priority(500) + #else + return self.priority(501) + #endif + } + + @available(*, deprecated:0.40.0, message:"Use priority(_ amount: ConstraintPriorityTarget) instead.") + @discardableResult + public func priorityLow() -> ConstraintMakerFinalizable { + return self.priority(250) + } + +} diff --git a/Source/ConstraintMakerRelatable.swift b/Source/ConstraintMakerRelatable.swift new file mode 100644 index 0000000..40a46fa --- /dev/null +++ b/Source/ConstraintMakerRelatable.swift @@ -0,0 +1,95 @@ +// +// 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 class ConstraintMakerRelatable { + + internal let description: ConstraintDescription + + internal init(_ description: ConstraintDescription) { + self.description = description + } + + internal func relatedTo(_ other: ConstraintRelatableTarget, relation: ConstraintRelation, file: String, line: UInt) -> ConstraintMakerEditable { + let related: ConstraintItem + let constant: ConstraintConstantTarget + + if let other = other as? ConstraintItem { + guard other.attributes == ConstraintAttributes.none || + other.attributes.layoutAttributes.count <= 1 || + other.attributes.layoutAttributes == self.description.attributes.layoutAttributes || + other.attributes == .edges && self.description.attributes == .margins || + other.attributes == .margins && self.description.attributes == .edges else { + fatalError("Cannot constraint to multiple non identical attributes. (\(file), \(line))"); + } + + related = other + constant = 0.0 + } else if let other = other as? ConstraintView { + related = ConstraintItem(target: other, attributes: ConstraintAttributes.none) + constant = 0.0 + } else if let other = other as? ConstraintConstantTarget { + related = ConstraintItem(target: nil, attributes: ConstraintAttributes.none) + constant = other + } else { + fatalError("Invalid constraint. (\(file), \(line))") + } + + let editable = ConstraintMakerEditable(self.description) + editable.description.sourceLocation = (file, line) + editable.description.relation = relation + editable.description.related = related + editable.description.constant = constant + return editable + } + + @discardableResult + public func equalTo(_ other: ConstraintRelatableTarget, _ file: String = #file, _ line: UInt = #line) -> ConstraintMakerEditable { + return self.relatedTo(other, relation: .equal, file: file, line: line) + } + + @discardableResult + public func equalToSuperview(_ file: String = #file, _ line: UInt = #line) -> ConstraintMakerEditable { + guard let other = self.description.view.superview else { + fatalError("Expected superview but found nil when attempting make constraint `equalToSuperview`.") + } + return self.relatedTo(other, relation: .equal, file: file, line: line) + } + + @discardableResult + public func lessThanOrEqualTo(_ other: ConstraintRelatableTarget, _ file: String = #file, _ line: UInt = #line) -> ConstraintMakerEditable { + return self.relatedTo(other, relation: .lessThanOrEqual, file: file, line: line) + } + + @discardableResult + public func greaterThanOrEqualTo(_ other: ConstraintRelatableTarget, _ file: String = #file, line: UInt = #line) -> ConstraintMakerEditable { + return self.relatedTo(other, relation: .greaterThanOrEqual, file: file, line: line) + } + +} diff --git a/Source/ConstraintMultiplierTarget.swift b/Source/ConstraintMultiplierTarget.swift new file mode 100644 index 0000000..6fecd33 --- /dev/null +++ b/Source/ConstraintMultiplierTarget.swift @@ -0,0 +1,75 @@ +// +// 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 protocol ConstraintMultiplierTarget { + + var constraintMultiplierTargetValue: CGFloat { get } + +} + +extension Int: ConstraintMultiplierTarget { + + public var constraintMultiplierTargetValue: CGFloat { + return CGFloat(self) + } + +} + +extension UInt: ConstraintMultiplierTarget { + + public var constraintMultiplierTargetValue: CGFloat { + return CGFloat(self) + } + +} + +extension Float: ConstraintMultiplierTarget { + + public var constraintMultiplierTargetValue: CGFloat { + return CGFloat(self) + } + +} + +extension Double: ConstraintMultiplierTarget { + + public var constraintMultiplierTargetValue: CGFloat { + return CGFloat(self) + } + +} + +extension CGFloat: ConstraintMultiplierTarget { + + public var constraintMultiplierTargetValue: CGFloat { + return self + } + +} diff --git a/Source/ConstraintOffsetTarget.swift b/Source/ConstraintOffsetTarget.swift new file mode 100644 index 0000000..bd9e0a1 --- /dev/null +++ b/Source/ConstraintOffsetTarget.swift @@ -0,0 +1,69 @@ +// +// 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 protocol ConstraintOffsetTarget: ConstraintConstantTarget { +} + +extension Int: ConstraintOffsetTarget { +} + +extension UInt: ConstraintOffsetTarget { +} + +extension Float: ConstraintOffsetTarget { +} + +extension Double: ConstraintOffsetTarget { +} + +extension CGFloat: ConstraintOffsetTarget { +} + +extension ConstraintOffsetTarget { + + internal var constraintOffsetTargetValue: CGFloat { + let offset: CGFloat + if let amount = self as? Float { + offset = CGFloat(amount) + } else if let amount = self as? Double { + offset = CGFloat(amount) + } else if let amount = self as? CGFloat { + offset = CGFloat(amount) + } else if let amount = self as? Int { + offset = CGFloat(amount) + } else if let amount = self as? UInt { + offset = CGFloat(amount) + } else { + offset = 0.0 + } + return offset + } + +} diff --git a/Source/ConstraintPriorityTarget.swift b/Source/ConstraintPriorityTarget.swift new file mode 100644 index 0000000..eb32f79 --- /dev/null +++ b/Source/ConstraintPriorityTarget.swift @@ -0,0 +1,75 @@ +// +// 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 protocol ConstraintPriorityTarget { + + var constraintPriorityTargetValue: Float { get } + +} + +extension Int: ConstraintPriorityTarget { + + public var constraintPriorityTargetValue: Float { + return Float(self) + } + +} + +extension UInt: ConstraintPriorityTarget { + + public var constraintPriorityTargetValue: Float { + return Float(self) + } + +} + +extension Float: ConstraintPriorityTarget { + + public var constraintPriorityTargetValue: Float { + return self + } + +} + +extension Double: ConstraintPriorityTarget { + + public var constraintPriorityTargetValue: Float { + return Float(self) + } + +} + +extension CGFloat: ConstraintPriorityTarget { + + public var constraintPriorityTargetValue: Float { + return Float(self) + } + +} diff --git a/Source/EdgeInsets.swift b/Source/ConstraintRelatableTarget.swift similarity index 62% rename from Source/EdgeInsets.swift rename to Source/ConstraintRelatableTarget.swift index 299874a..4d1e37d 100644 --- a/Source/EdgeInsets.swift +++ b/Source/ConstraintRelatableTarget.swift @@ -1,7 +1,7 @@ // // SnapKit // -// Copyright (c) 2011-2015 SnapKit Team - https://github.com/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 @@ -22,17 +22,41 @@ // THE SOFTWARE. #if os(iOS) || os(tvOS) -import UIKit -public typealias EdgeInsets = UIEdgeInsets -public func EdgeInsetsMake(top: CGFloat, left: CGFloat, bottom: CGFloat, right: CGFloat) -> EdgeInsets { - return EdgeInsets(top: top, left: left, bottom: bottom, right: right) -} -public let EdgeInsetsZero = EdgeInsets(top: 0, left: 0, bottom: 0, right: 0) + import UIKit #else -import AppKit -public typealias EdgeInsets = NSEdgeInsets -public func EdgeInsetsMake(top: CGFloat, left: CGFloat, bottom: CGFloat, right: CGFloat) -> EdgeInsets { - return EdgeInsets(top: top, left: left, bottom: bottom, right: right) -} -public let EdgeInsetsZero = EdgeInsets(top: 0, left: 0, bottom: 0, right: 0) + import AppKit #endif + + +public protocol ConstraintRelatableTarget { +} + +extension Int: ConstraintRelatableTarget { +} + +extension UInt: ConstraintRelatableTarget { +} + +extension Float: ConstraintRelatableTarget { +} + +extension Double: ConstraintRelatableTarget { +} + +extension CGFloat: ConstraintRelatableTarget { +} + +extension CGSize: ConstraintRelatableTarget { +} + +extension CGPoint: ConstraintRelatableTarget { +} + +extension ConstraintInsets: ConstraintRelatableTarget { +} + +extension ConstraintItem: ConstraintRelatableTarget { +} + +extension ConstraintView: ConstraintRelatableTarget { +} diff --git a/Source/ConstraintRelation.swift b/Source/ConstraintRelation.swift index f1b1ab2..48afbfc 100644 --- a/Source/ConstraintRelation.swift +++ b/Source/ConstraintRelation.swift @@ -1,7 +1,7 @@ // // SnapKit // -// Copyright (c) 2011-2015 SnapKit Team - https://github.com/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 @@ -22,27 +22,27 @@ // THE SOFTWARE. #if os(iOS) || os(tvOS) -import UIKit + import UIKit #else -import AppKit + import AppKit #endif -/** - Used to define `NSLayoutRelation` -*/ + internal enum ConstraintRelation: Int { - case Equal = 1, LessThanOrEqualTo, GreaterThanOrEqualTo + case equal = 1 + case lessThanOrEqual + case greaterThanOrEqual internal var layoutRelation: NSLayoutRelation { get { switch(self) { - case .LessThanOrEqualTo: - return .LessThanOrEqual - case .GreaterThanOrEqualTo: - return .GreaterThanOrEqual - default: - return .Equal + case .equal: + return .equal + case .lessThanOrEqual: + return .lessThanOrEqual + case .greaterThanOrEqual: + return .greaterThanOrEqual } } } -} \ No newline at end of file +} diff --git a/Source/ConstraintView+Extensions.swift b/Source/ConstraintView+Extensions.swift new file mode 100644 index 0000000..b9634e7 --- /dev/null +++ b/Source/ConstraintView+Extensions.swift @@ -0,0 +1,152 @@ +// +// 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 ConstraintView { + + @available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.") + public var snp_left: ConstraintItem { return self.snp.left } + + @available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.") + public var snp_top: ConstraintItem { return self.snp.top } + + @available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.") + public var snp_right: ConstraintItem { return self.snp.right } + + @available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.") + public var snp_bottom: ConstraintItem { return self.snp.bottom } + + @available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.") + public var snp_leading: ConstraintItem { return self.snp.leading } + + @available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.") + public var snp_trailing: ConstraintItem { return self.snp.trailing } + + @available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.") + public var snp_width: ConstraintItem { return self.snp.width } + + @available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.") + public var snp_height: ConstraintItem { return self.snp.height } + + @available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.") + public var snp_centerX: ConstraintItem { return self.snp.centerX } + + @available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.") + public var snp_centerY: ConstraintItem { return self.snp.centerY } + + @available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.") + public var snp_baseline: ConstraintItem { return self.snp.baseline } + + @available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.") + @available(iOS 8.0, OSX 10.11, *) + public var snp_lastBaseline: ConstraintItem { return self.snp.lastBaseline } + + @available(iOS, deprecated:0.40.0, message:"Use newer snp.* syntax.") + @available(iOS 8.0, OSX 10.11, *) + public var snp_firstBaseline: ConstraintItem { return self.snp.firstBaseline } + + @available(iOS, deprecated:0.40.0, message:"Use newer snp.* syntax.") + @available(iOS 8.0, *) + public var snp_leftMargin: ConstraintItem { return self.snp.leftMargin } + + @available(iOS, deprecated:0.40.0, message:"Use newer snp.* syntax.") + @available(iOS 8.0, *) + public var snp_topMargin: ConstraintItem { return self.snp.topMargin } + + @available(iOS, deprecated:0.40.0, message:"Use newer snp.* syntax.") + @available(iOS 8.0, *) + public var snp_rightMargin: ConstraintItem { return self.snp.rightMargin } + + @available(iOS, deprecated:0.40.0, message:"Use newer snp.* syntax.") + @available(iOS 8.0, *) + public var snp_bottomMargin: ConstraintItem { return self.snp.bottomMargin } + + @available(iOS, deprecated:0.40.0, message:"Use newer snp.* syntax.") + @available(iOS 8.0, *) + public var snp_leadingMargin: ConstraintItem { return self.snp.leadingMargin } + + @available(iOS, deprecated:0.40.0, message:"Use newer snp.* syntax.") + @available(iOS 8.0, *) + public var snp_trailingMargin: ConstraintItem { return self.snp.trailingMargin } + + @available(iOS, deprecated:0.40.0, message:"Use newer snp.* syntax.") + @available(iOS 8.0, *) + public var snp_centerXWithinMargins: ConstraintItem { return self.snp.centerXWithinMargins } + + @available(iOS, deprecated:0.40.0, message:"Use newer snp.* syntax.") + @available(iOS 8.0, *) + public var snp_centerYWithinMargins: ConstraintItem { return self.snp.centerYWithinMargins } + + @available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.") + public var snp_edges: ConstraintItem { return self.snp.edges } + + @available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.") + public var snp_size: ConstraintItem { return self.snp.size } + + @available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.") + public var snp_center: ConstraintItem { return self.snp.center } + + @available(iOS, deprecated:0.40.0, message:"Use newer snp.* syntax.") + @available(iOS 8.0, *) + public var snp_margins: ConstraintItem { return self.snp.margins } + + @available(iOS, deprecated:0.40.0, message:"Use newer snp.* syntax.") + @available(iOS 8.0, *) + public var snp_centerWithinMargins: ConstraintItem { return self.snp.centerWithinMargins } + + @available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.") + public func snp_prepareConstraints(_ closure: (_ make: ConstraintMaker) -> Void) -> [Constraint] { + return self.snp.prepareConstraints(closure) + } + + @available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.") + public func snp_makeConstraints(_ closure: (_ make: ConstraintMaker) -> Void) { + self.snp.makeConstraints(closure) + } + + @available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.") + public func snp_remakeConstraints(_ closure: (_ make: ConstraintMaker) -> Void) { + self.snp.remakeConstraints(closure) + } + + @available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.") + public func snp_updateConstraints(_ closure: (_ make: ConstraintMaker) -> Void) { + self.snp.updateConstraints(closure) + } + + @available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.") + public func snp_removeConstraints() { + self.snp.removeConstraints() + } + + public var snp: ConstraintViewDSL { + return ConstraintViewDSL(view: self) + } + +} diff --git a/Source/ConstraintView.swift b/Source/ConstraintView.swift new file mode 100644 index 0000000..6ff8a76 --- /dev/null +++ b/Source/ConstraintView.swift @@ -0,0 +1,35 @@ +// +// 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 + + +#if os(iOS) || os(tvOS) + public typealias ConstraintView = UIView +#else + public typealias ConstraintView = NSView +#endif diff --git a/Source/ConstraintViewDSL.swift b/Source/ConstraintViewDSL.swift new file mode 100644 index 0000000..55bb845 --- /dev/null +++ b/Source/ConstraintViewDSL.swift @@ -0,0 +1,135 @@ +// +// 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 struct ConstraintViewDSL: ConstraintAttributesDSL { + + @discardableResult + public func prepareConstraints(_ closure: (_ make: ConstraintMaker) -> Void) -> [Constraint] { + return ConstraintMaker.prepareConstraints(view: self.view, closure: closure) + } + + public func makeConstraints(_ closure: (_ make: ConstraintMaker) -> Void) { + ConstraintMaker.makeConstraints(view: self.view, closure: closure) + } + + public func remakeConstraints(_ closure: (_ make: ConstraintMaker) -> Void) { + ConstraintMaker.remakeConstraints(view: self.view, closure: closure) + } + + public func updateConstraints(_ closure: (_ make: ConstraintMaker) -> Void) { + ConstraintMaker.updateConstraints(view: self.view, closure: closure) + } + + public func removeConstraints() { + ConstraintMaker.removeConstraints(view: self.view) + } + + + + public var contentHuggingHorizontalPriority: Float { + get { + return self.view.contentHuggingPriority(for: .horizontal) + } + set { + self.view.setContentHuggingPriority(newValue, for: .horizontal) + } + } + + public var contentHuggingVerticalPriority: Float { + get { + return self.view.contentHuggingPriority(for: .vertical) + } + set { + self.view.setContentHuggingPriority(newValue, for: .vertical) + } + } + + public var contentCompressionResistanceHorizontalPriority: Float { + get { + return self.view.contentCompressionResistancePriority(for: .horizontal) + } + set { + self.view.setContentHuggingPriority(newValue, for: .horizontal) + } + } + + public var contentCompressionResistanceVerticalPriority: Float { + get { + return self.view.contentCompressionResistancePriority(for: .vertical) + } + set { + self.view.setContentCompressionResistancePriority(newValue, for: .vertical) + } + } + + public var target: AnyObject? { + return self.view + } + + internal let view: ConstraintView + + internal init(view: ConstraintView) { + self.view = view + + } + + internal var layoutConstraints: [LayoutConstraint] { + return self.layoutConstraintsHashTable.allObjects + } + + internal func add(layoutConstraints: [LayoutConstraint]) { + let hashTable = self.layoutConstraintsHashTable + for layoutConstraint in layoutConstraints { + hashTable.add(layoutConstraint) + } + } + + internal func remove(layoutConstraints: [LayoutConstraint]) { + let hashTable = self.layoutConstraintsHashTable + for layoutConstraint in layoutConstraints { + hashTable.remove(layoutConstraint) + } + } + + private var layoutConstraintsHashTable: NSHashTable { + let layoutConstraints: NSHashTable + + if let existing = objc_getAssociatedObject(self.view, &layoutConstraintsKey) as? NSHashTable { + layoutConstraints = existing + } else { + layoutConstraints = NSHashTable.weakObjects() + objc_setAssociatedObject(self.view, &layoutConstraintsKey, layoutConstraints, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) + } + return layoutConstraints + + } + +} +private var layoutConstraintsKey: UInt8 = 0 diff --git a/Source/Debugging.swift b/Source/Debugging.swift index 893f66d..be8bb9e 100644 --- a/Source/Debugging.swift +++ b/Source/Debugging.swift @@ -1,7 +1,7 @@ // // SnapKit // -// Copyright (c) 2011-2015 SnapKit Team - https://github.com/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 @@ -22,75 +22,47 @@ // THE SOFTWARE. #if os(iOS) || os(tvOS) -import UIKit + import UIKit #else -import AppKit + import AppKit #endif -/** - Used to allow adding a snp_label to a View for debugging purposes -*/ -public extension View { - - public var snp_label: String? { - get { - return objc_getAssociatedObject(self, &labelKey) as? String - } - set { - objc_setAssociatedObject(self, &labelKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_COPY_NONATOMIC) - } - } - -} - -/** - Used to allow adding a snp_label to a LayoutConstraint for debugging purposes -*/ public extension LayoutConstraint { - public var snp_label: String? { - get { - return objc_getAssociatedObject(self, &labelKey) as? String - } - set { - objc_setAssociatedObject(self, &labelKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_COPY_NONATOMIC) - } - } - override public var description: String { var description = "<" description += descriptionForObject(self) - if let firstItem: AnyObject = self.firstItem { + if let firstItem = conditionalOptional(from: self.firstItem) { description += " \(descriptionForObject(firstItem))" } - if self.firstAttribute != .NotAnAttribute { - description += ".\(self.firstAttribute.snp_description)" + if self.firstAttribute != .notAnAttribute { + description += ".\(descriptionForAttribute(self.firstAttribute))" } - description += " \(self.relation.snp_description)" + description += " \(descriptionForRelation(self.relation))" - if let secondItem: AnyObject = self.secondItem { + if let secondItem = self.secondItem { description += " \(descriptionForObject(secondItem))" } - if self.secondAttribute != .NotAnAttribute { - description += ".\(self.secondAttribute.snp_description)" + if self.secondAttribute != .notAnAttribute { + description += ".\(descriptionForAttribute(self.secondAttribute))" } if self.multiplier != 1.0 { description += " * \(self.multiplier)" } - if self.secondAttribute == .NotAnAttribute { + if self.secondAttribute == .notAnAttribute { description += " \(self.constant)" } else { if self.constant > 0.0 { description += " + \(self.constant)" } else if self.constant < 0.0 { - description += " - \(CGFloat.abs(self.constant))" + description += " - \(abs(self.constant))" } } @@ -103,97 +75,86 @@ public extension LayoutConstraint { return description } - internal var snp_makerFile: String? { - return self.snp_constraint?.makerFile - } - - internal var snp_makerLine: UInt? { - return self.snp_constraint?.makerLine - } - } -private var labelKey = "" +private func descriptionForRelation(_ relation: NSLayoutRelation) -> String { + switch relation { + case .equal: return "==" + case .greaterThanOrEqual: return ">=" + case .lessThanOrEqual: return "<=" + } +} -private func descriptionForObject(object: AnyObject) -> String { - let pointerDescription = NSString(format: "%p", ObjectIdentifier(object).uintValue) +private func descriptionForAttribute(_ attribute: NSLayoutAttribute) -> String { + #if os(iOS) || os(tvOS) + switch attribute { + case .notAnAttribute: return "notAnAttribute" + case .top: return "top" + case .left: return "left" + case .bottom: return "bottom" + case .right: return "right" + case .leading: return "leading" + case .trailing: return "trailing" + case .width: return "width" + case .height: return "height" + case .centerX: return "centerX" + case .centerY: return "centerY" + case .lastBaseline: return "lastBaseline" + case .firstBaseline: return "firstBaseline" + case .topMargin: return "topMargin" + case .leftMargin: return "leftMargin" + case .bottomMargin: return "bottomMargin" + case .rightMargin: return "rightMargin" + case .leadingMargin: return "leadingMargin" + case .trailingMargin: return "trailingMargin" + case .centerXWithinMargins: return "centerXWithinMargins" + case .centerYWithinMargins: return "centerYWithinMargins" + } + #else + switch attribute { + case .notAnAttribute: return "notAnAttribute" + case .top: return "top" + case .left: return "left" + case .bottom: return "bottom" + case .right: return "right" + case .leading: return "leading" + case .trailing: return "trailing" + case .width: return "width" + case .height: return "height" + case .centerX: return "centerX" + case .centerY: return "centerY" + case .lastBaseline: return "lastBaseline" + case .firstBaseline: return "firstBaseline" + } + #endif +} + +private func conditionalOptional(from object: Optional) -> Optional { + return object +} + +private func conditionalOptional(from object: T) -> Optional { + return Optional.some(object) +} + +private func descriptionForObject(_ object: AnyObject) -> String { + let pointerDescription = String(format: "%p", UInt(bitPattern: ObjectIdentifier(object))) var desc = "" - desc += object.dynamicType.description() + desc += type(of: object).description() - if let object = object as? View { - desc += ":\(object.snp_label ?? pointerDescription)" + if let object = object as? ConstraintView { + desc += ":\(object.snp.label ?? pointerDescription)" } else if let object = object as? LayoutConstraint { - desc += ":\(object.snp_label ?? pointerDescription)" + desc += ":\(object.label ?? pointerDescription)" } else { desc += ":\(pointerDescription)" } - if let object = object as? LayoutConstraint, let file = object.snp_makerFile, let line = object.snp_makerLine { - desc += "@\(file)#\(line)" + if let object = object as? LayoutConstraint, let file = object.constraint?.sourceLocation.0, let line = object.constraint?.sourceLocation.1 { + desc += "@\((file as NSString).lastPathComponent)#\(line)" } desc += "" return desc } - -private extension NSLayoutRelation { - - private var snp_description: String { - switch self { - case .Equal: return "==" - case .GreaterThanOrEqual: return ">=" - case .LessThanOrEqual: return "<=" - } - } - -} - -private extension NSLayoutAttribute { - - private var snp_description: String { - #if os(iOS) || os(tvOS) - switch self { - case .NotAnAttribute: return "notAnAttribute" - case .Top: return "top" - case .Left: return "left" - case .Bottom: return "bottom" - case .Right: return "right" - case .Leading: return "leading" - case .Trailing: return "trailing" - case .Width: return "width" - case .Height: return "height" - case .CenterX: return "centerX" - case .CenterY: return "centerY" - case .LastBaseline: return "baseline" - case .FirstBaseline: return "firstBaseline" - case .TopMargin: return "topMargin" - case .LeftMargin: return "leftMargin" - case .BottomMargin: return "bottomMargin" - case .RightMargin: return "rightMargin" - case .LeadingMargin: return "leadingMargin" - case .TrailingMargin: return "trailingMargin" - case .CenterXWithinMargins: return "centerXWithinMargins" - case .CenterYWithinMargins: return "centerYWithinMargins" - } - #else - switch self { - case .NotAnAttribute: return "notAnAttribute" - case .Top: return "top" - case .Left: return "left" - case .Bottom: return "bottom" - case .Right: return "right" - case .Leading: return "leading" - case .Trailing: return "trailing" - case .Width: return "width" - case .Height: return "height" - case .CenterX: return "centerX" - case .CenterY: return "centerY" - case .LastBaseline: return "baseline" - default: return "default" - } - #endif - - } - -} diff --git a/Source/LayoutConstraint.swift b/Source/LayoutConstraint.swift index 14ec1ed..3dbe3ab 100644 --- a/Source/LayoutConstraint.swift +++ b/Source/LayoutConstraint.swift @@ -1,7 +1,7 @@ // // SnapKit // -// Copyright (c) 2011-2015 SnapKit Team - https://github.com/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 @@ -22,42 +22,36 @@ // THE SOFTWARE. #if os(iOS) || os(tvOS) -import UIKit + import UIKit #else -import AppKit + import AppKit #endif -/** - Used to add extra information to the actual `NSLayoutConstraint`'s that will UIKit/AppKit will utilize -*/ + public class LayoutConstraint: NSLayoutConstraint { - internal var snp_constraint: Constraint? = nil + public var label: String? { + get { + return self.identifier + } + set { + self.identifier = newValue + } + } + + internal var constraint: Constraint! = nil } -internal func ==(left: LayoutConstraint, right: LayoutConstraint) -> Bool { - if left.firstItem !== right.firstItem { - return false - } - if left.secondItem !== right.secondItem { - return false - } - if left.firstAttribute != right.firstAttribute { - return false - } - if left.secondAttribute != right.secondAttribute { - return false - } - if left.relation != right.relation { - return false - } - if left.priority != right.priority { - return false - } - if left.multiplier != right.multiplier { +internal func ==(lhs: LayoutConstraint, rhs: LayoutConstraint) -> Bool { + guard lhs.firstItem === rhs.firstItem && + lhs.secondItem === rhs.secondItem && + lhs.firstAttribute == rhs.firstAttribute && + lhs.secondAttribute == rhs.secondAttribute && + lhs.relation == rhs.relation && + lhs.priority == rhs.priority && + lhs.multiplier == rhs.multiplier else { return false } return true } - diff --git a/Source/UILayoutGuide+Extensions.swift b/Source/UILayoutGuide+Extensions.swift new file mode 100644 index 0000000..cd89d8a --- /dev/null +++ b/Source/UILayoutGuide+Extensions.swift @@ -0,0 +1,36 @@ +// +// 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 +#endif + + +@available(iOS 9.0, *) +public extension ConstraintLayoutGuide { + + public var snp: ConstraintLayoutGuideDSL { + return ConstraintLayoutGuideDSL(guide: self) + } + +} diff --git a/Source/UILayoutSupport+Extensions.swift b/Source/UILayoutSupport+Extensions.swift new file mode 100644 index 0000000..cfbce2e --- /dev/null +++ b/Source/UILayoutSupport+Extensions.swift @@ -0,0 +1,36 @@ +// +// 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 +#endif + + +@available(iOS 8.0, *) +public extension ConstraintLayoutSupport { + + public var snp: ConstraintLayoutSupportDSL { + return ConstraintLayoutSupportDSL(support: self) + } + +} diff --git a/Source/View+SnapKit.swift b/Source/View+SnapKit.swift deleted file mode 100644 index 51cde58..0000000 --- a/Source/View+SnapKit.swift +++ /dev/null @@ -1,183 +0,0 @@ -// -// SnapKit -// -// Copyright (c) 2011-2015 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 -public typealias View = UIView -#else -import AppKit -public typealias View = NSView -#endif - -/** - Used to expose public API on views -*/ -public extension View { - - /// 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 - @available(iOS 8.0, *) - public var snp_firstBaseline: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.FirstBaseline) } - - /// left margin - @available(iOS 8.0, *) - public var snp_leftMargin: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.LeftMargin) } - - /// right margin - @available(iOS 8.0, *) - public var snp_rightMargin: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.RightMargin) } - - /// top margin - @available(iOS 8.0, *) - public var snp_topMargin: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.TopMargin) } - - /// bottom margin - @available(iOS 8.0, *) - public var snp_bottomMargin: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.BottomMargin) } - - /// leading margin - @available(iOS 8.0, *) - public var snp_leadingMargin: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.LeadingMargin) } - - /// trailing margin - @available(iOS 8.0, *) - public var snp_trailingMargin: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.TrailingMargin) } - - /// centerX within margins - @available(iOS 8.0, *) - public var snp_centerXWithinMargins: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.CenterXWithinMargins) } - - /// centerY within margins - @available(iOS 8.0, *) - 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 - @available(iOS 8.0, *) - public var snp_margins: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.Margins) } - - // centerX + centerY within margins - @available(iOS 8.0, *) - public var snp_centerWithinMargins: ConstraintItem { return ConstraintItem(object: self, attributes: ConstraintAttributes.CenterWithinMargins) } - - /** - Prepares constraints with a `ConstraintMaker` and returns the made constraints but does not install them. - - - parameter closure that will be passed the `ConstraintMaker` to make the constraints with - - - returns: the constraints made - */ - public func snp_prepareConstraints(file: String = #file, line: UInt = #line, @noescape closure: (make: ConstraintMaker) -> Void) -> [Constraint] { - return ConstraintMaker.prepareConstraints(view: self, file: file, line: line, closure: closure) - } - - /** - Makes constraints with a `ConstraintMaker` and installs them along side any previous made constraints. - - - parameter closure that will be passed the `ConstraintMaker` to make the constraints with - */ - public func snp_makeConstraints(file: String = #file, line: UInt = #line, @noescape closure: (make: ConstraintMaker) -> Void) -> Void { - ConstraintMaker.makeConstraints(view: self, file: file, line: line, closure: closure) - } - - /** - Updates constraints with a `ConstraintMaker` that will replace existing constraints that match and install new ones. - - For constraints to match only the constant can be updated. - - - parameter closure that will be passed the `ConstraintMaker` to update the constraints with - */ - public func snp_updateConstraints(file: String = #file, line: UInt = #line, @noescape closure: (make: ConstraintMaker) -> Void) -> Void { - ConstraintMaker.updateConstraints(view: self, file: file, line: line, closure: closure) - } - - /** - Remakes constraints with a `ConstraintMaker` that will first remove all previously made constraints and make and install new ones. - - - parameter closure that will be passed the `ConstraintMaker` to remake the constraints with - */ - public func snp_remakeConstraints(file: String = #file, line: UInt = #line, @noescape closure: (make: ConstraintMaker) -> Void) -> Void { - ConstraintMaker.remakeConstraints(view: self, file: file, line: line, closure: closure) - } - - /** - Removes all previously made constraints. - */ - public func snp_removeConstraints() { - ConstraintMaker.removeConstraints(view: self) - } - - internal var snp_installedLayoutConstraints: [LayoutConstraint] { - get { - if let constraints = objc_getAssociatedObject(self, &installedLayoutConstraintsKey) as? [LayoutConstraint] { - return constraints - } - return [] - } - set { - objc_setAssociatedObject(self, &installedLayoutConstraintsKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC) - } - } -} - -private var installedLayoutConstraintsKey = "" diff --git a/Tests/Tests.swift b/Tests/Tests.swift index d317194..8b1c83c 100644 --- a/Tests/Tests.swift +++ b/Tests/Tests.swift @@ -13,7 +13,7 @@ extension View { #endif import XCTest -import SnapKit +@testable import SnapKit class SnapKitTests: XCTestCase { @@ -29,37 +29,21 @@ class SnapKitTests: XCTestCase { super.tearDown() } - func testLayoutGuideConstraints() { - #if os(iOS) || os(tvOS) - let vc = UIViewController() - vc.view = UIView(frame: CGRectMake(0, 0, 300, 300)) - - vc.view.addSubview(self.container) - - self.container.snp_makeConstraints { (make) -> Void in - make.top.equalTo(vc.snp_topLayoutGuideBottom) - make.bottom.equalTo(vc.snp_bottomLayoutGuideTop) - } - - XCTAssertEqual(vc.view.snp_constraints.count, 6, "Should have 6 constraints installed") - #endif - } - func testMakeConstraints() { let v1 = View() let v2 = View() self.container.addSubview(v1) self.container.addSubview(v2) - v1.snp_makeConstraints { (make) -> Void in - make.top.equalTo(v2.snp_top).offset(50) - make.left.equalTo(v2.snp_top).offset(50) + v1.snp.makeConstraints { (make) -> Void in + make.top.equalTo(v2.snp.top).offset(50) + make.left.equalTo(v2.snp.top).offset(50) return } XCTAssertEqual(self.container.snp_constraints.count, 2, "Should have 2 constraints installed") - v2.snp_makeConstraints { (make) -> Void in + v2.snp.makeConstraints { (make) -> Void in make.edges.equalTo(v1) return } @@ -68,22 +52,44 @@ class SnapKitTests: XCTestCase { } + func testMakeImpliedSuperviewConstraints() { + let v1 = View() + let v2 = View() + self.container.addSubview(v1) + self.container.addSubview(v2) + + v1.snp.makeConstraints { (make) -> Void in + make.top.equalTo(50.0) + make.left.equalTo(50.0) + return + } + + XCTAssertEqual(self.container.snp_constraints.count, 2, "Should have 2 constraints installed") + + v2.snp.makeConstraints { (make) -> Void in + make.edges.equalTo(v1) + return + } + + XCTAssertEqual(self.container.snp_constraints.count, 6, "Should have 6 constraints installed") + } + func testUpdateConstraints() { let v1 = View() let v2 = View() self.container.addSubview(v1) self.container.addSubview(v2) - v1.snp_makeConstraints { (make) -> Void in - make.top.equalTo(v2.snp_top).offset(50) - make.left.equalTo(v2.snp_top).offset(50) + v1.snp.makeConstraints { (make) -> Void in + make.top.equalTo(v2.snp.top).offset(50) + make.left.equalTo(v2.snp.top).offset(50) return } XCTAssertEqual(self.container.snp_constraints.count, 2, "Should have 2 constraints installed") - v1.snp_updateConstraints { (make) -> Void in - make.top.equalTo(v2.snp_top).offset(15) + v1.snp.updateConstraints { (make) -> Void in + make.top.equalTo(v2.snp.top).offset(15) return } @@ -91,21 +97,22 @@ class SnapKitTests: XCTestCase { } + func testRemakeConstraints() { let v1 = View() let v2 = View() self.container.addSubview(v1) self.container.addSubview(v2) - v1.snp_makeConstraints { (make) -> Void in - make.top.equalTo(v2.snp_top).offset(50) - make.left.equalTo(v2.snp_top).offset(50) + v1.snp.makeConstraints { (make) -> Void in + make.top.equalTo(v2.snp.top).offset(50) + make.left.equalTo(v2.snp.top).offset(50) return } XCTAssertEqual(self.container.snp_constraints.count, 2, "Should have 2 constraints installed") - v1.snp_remakeConstraints { (make) -> Void in + v1.snp.remakeConstraints { (make) -> Void in make.edges.equalTo(v2) return } @@ -120,15 +127,15 @@ class SnapKitTests: XCTestCase { self.container.addSubview(v1) self.container.addSubview(v2) - v1.snp_makeConstraints { (make) -> Void in - make.top.equalTo(v2.snp_top).offset(50) - make.left.equalTo(v2.snp_top).offset(50) + v1.snp.makeConstraints { (make) -> Void in + make.top.equalTo(v2.snp.top).offset(50) + make.left.equalTo(v2.snp.top).offset(50) return } XCTAssertEqual(self.container.snp_constraints.count, 2, "Should have 2 constraints installed") - v1.snp_removeConstraints() + v1.snp.removeConstraints() XCTAssertEqual(self.container.snp_constraints.count, 0, "Should have 0 constraints installed") @@ -140,7 +147,7 @@ class SnapKitTests: XCTestCase { self.container.addSubview(v1) self.container.addSubview(v2) - let constraints = v1.snp_prepareConstraints { (make) -> Void in + let constraints = v1.snp.prepareConstraints { (make) -> Void in make.edges.equalTo(v2) return } @@ -148,26 +155,26 @@ class SnapKitTests: XCTestCase { XCTAssertEqual(self.container.snp_constraints.count, 0, "Should have 0 constraints installed") for constraint in constraints { - constraint.install() + constraint.activate() } XCTAssertEqual(self.container.snp_constraints.count, 4, "Should have 4 constraints installed") for constraint in constraints { - constraint.uninstall() + constraint.deactivate() } XCTAssertEqual(self.container.snp_constraints.count, 0, "Should have 0 constraints installed") } - func testReinstallConstraints() { + func testReactivateConstraints() { let v1 = View() let v2 = View() self.container.addSubview(v1) self.container.addSubview(v2) - let constraints = v1.snp_prepareConstraints { (make) -> Void in + let constraints = v1.snp.prepareConstraints { (make) -> Void in make.edges.equalTo(v2) return } @@ -176,16 +183,16 @@ class SnapKitTests: XCTestCase { XCTAssertEqual(self.container.snp_constraints.count, 0, "Should have 0 constraints installed") for constraint in constraints { - constraint.install() + constraint.activate() } XCTAssertEqual(self.container.snp_constraints.count, 4, "Should have 4 constraints installed") for constraint in constraints { - constraint.install() + constraint.deactivate() } - XCTAssertEqual(self.container.snp_constraints.count, 4, "Should have 0 constraints installed") + XCTAssertEqual(self.container.snp_constraints.count, 0, "Should have 0 constraints installed") } func testActivateDeactivateConstraints() { @@ -197,9 +204,9 @@ class SnapKitTests: XCTestCase { 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 + 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 } @@ -215,11 +222,6 @@ class SnapKitTests: XCTestCase { XCTAssertEqual(self.container.snp_constraints.count, 0, "Should have 0 constraints") - c1?.uninstall() - c2?.uninstall() - - XCTAssertEqual(self.container.snp_constraints.count, 0, "Should have 0 constraints") - c1?.activate() c2?.activate() @@ -227,12 +229,127 @@ class SnapKitTests: XCTestCase { } + func testEdgeConstraints() { + let view = View() + self.container.addSubview(view) + + view.snp.makeConstraints { (make) -> Void in + make.edges.equalTo(self.container).offset(50.0) + } + + XCTAssertEqual(self.container.snp_constraints.count, 4, "Should have 4 constraints") + + + let constraints = self.container.snp_constraints as! [NSLayoutConstraint] + + XCTAssertEqual(constraints[0].constant, 50, "Should be 50") + XCTAssertEqual(constraints[1].constant, 50, "Should be 50") + XCTAssertEqual(constraints[2].constant, 50, "Should be 50") + XCTAssertEqual(constraints[3].constant, 50, "Should be 50") + } + + func testUpdateReferencedConstraints() { + let v1 = View() + let v2 = View() + self.container.addSubview(v1) + self.container.addSubview(v2) + + var c1: Constraint! = nil + var c2: Constraint! = nil + + v1.snp.makeConstraints { (make) -> Void in + c1 = make.top.equalTo(v2).offset(50).constraint + c2 = make.bottom.equalTo(v2).offset(25).constraint + return + } + + XCTAssertEqual(self.container.snp_constraints.count, 2, "Should have 2 constraints") + + let constraints = (self.container.snp_constraints as! [NSLayoutConstraint]).sorted { $0.constant > $1.constant } + + XCTAssertEqual(constraints[0].constant, 50, "Should be 50") + XCTAssertEqual(constraints[1].constant, 25, "Should be 25") + + c1.update(offset: 15) + c2.update(offset: 20) + + XCTAssertEqual(self.container.snp_constraints.count, 2, "Should have 2 constraints") + + XCTAssertEqual(constraints[0].constant, 15, "Should be 15") + XCTAssertEqual(constraints[1].constant, 20, "Should be 20") + + c1.update(inset: 15) + c2.update(inset: 20) + + XCTAssertEqual(self.container.snp_constraints.count, 2, "Should have 2 constraints") + + XCTAssertEqual(constraints[0].constant, 15, "Should be 15") + XCTAssertEqual(constraints[1].constant, -20, "Should be -20") + + } + + func testInsetsAsConstraintsConstant() { + let view = View() + self.container.addSubview(view) + + view.snp.makeConstraints { (make) -> Void in + make.edges.equalTo(self.container).inset(50.0) + } + + 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, 50, "Should be 50") + XCTAssertEqual(constraints[1].constant, 50, "Should be 50") + XCTAssertEqual(constraints[2].constant, -50, "Should be -50") + XCTAssertEqual(constraints[3].constant, -50, "Should be -50") + } + + func testConstraintInsetsAsImpliedEqualToConstraints() { + let view = View() + self.container.addSubview(view) + + view.snp.makeConstraints { (make) -> Void in + make.edges.equalTo(ConstraintInsets(top: 25, left: 25, bottom: 25, right: 25)) + } + + 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, 25, "Should be 25") + XCTAssertEqual(constraints[1].constant, 25, "Should be 25") + XCTAssertEqual(constraints[2].constant, -25, "Should be -25") + XCTAssertEqual(constraints[3].constant, -25, "Should be -25") + } + + func testConstraintInsetsAsConstraintsConstant() { + let view = View() + self.container.addSubview(view) + + view.snp.makeConstraints { (make) -> Void in + make.edges.equalTo(self.container).inset(ConstraintInsets(top: 25, left: 25, bottom: 25, right: 25)) + } + + 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, 25, "Should be 25") + XCTAssertEqual(constraints[1].constant, 25, "Should be 25") + XCTAssertEqual(constraints[2].constant, -25, "Should be -25") + XCTAssertEqual(constraints[3].constant, -25, "Should be -25") + } + func testSizeConstraints() { let view = View() self.container.addSubview(view) - view.snp_makeConstraints { (make) -> Void in - make.size.equalTo(CGSizeMake(50, 50)) + view.snp.makeConstraints { (make) -> Void in + make.size.equalTo(CGSize(width: 50, height: 50)) make.left.top.equalTo(self.container) } @@ -240,11 +357,32 @@ class SnapKitTests: XCTestCase { XCTAssertEqual(self.container.snp_constraints.count, 2, "Should have 2 constraints") - let constraints = view.snp_constraints as! [NSLayoutConstraint] + + // no guarantee which order the constraints are in, but we should test their couple + let widthHeight = (NSLayoutAttribute.width.rawValue, NSLayoutAttribute.height.rawValue) + let heightWidth = (widthHeight.1, widthHeight.0) + let firstSecond = (constraints[0].firstAttribute.rawValue, constraints[1].firstAttribute.rawValue) + + // constraint values are correct in either width, height or height, width order + XCTAssertTrue(firstSecond == widthHeight || firstSecond == heightWidth, "2 contraint values should match") + XCTAssertEqual(constraints[0].constant, 50, "Should be 50") + XCTAssertEqual(constraints[1].constant, 50, "Should be 50") + } + + func testCenterConstraints() { + let view = View() + self.container.addSubview(view) + + view.snp.makeConstraints { (make) -> Void in + make.center.equalTo(self.container).offset(50.0) + } + + XCTAssertEqual(self.container.snp_constraints.count, 2, "Should have 2 constraints") + + + let constraints = self.container.snp_constraints as! [NSLayoutConstraint] - XCTAssertEqual(constraints[0].firstAttribute, NSLayoutAttribute.Width, "Should be width") - XCTAssertEqual(constraints[1].firstAttribute, NSLayoutAttribute.Height, "Should be height") XCTAssertEqual(constraints[0].constant, 50, "Should be 50") XCTAssertEqual(constraints[1].constant, 50, "Should be 50") } @@ -254,64 +392,90 @@ class SnapKitTests: XCTestCase { let view = View() self.container.addSubview(view) - view.snp_makeConstraints { (make) -> Void in - make.top.equalTo(self.container.snp_top).labeled(identifier) + view.snp.makeConstraints { (make) -> Void in + make.top.equalTo(self.container.snp.top).labeled(identifier) } let constraints = container.snp_constraints as! [NSLayoutConstraint] XCTAssertEqual(constraints[0].identifier, identifier, "Identifier should be 'Test'") } - func testSuperviewConstraints() { + #if os(iOS) || os(tvOS) + func testEdgesToMargins() { + var fromAttributes = Set() + var toAttributes = Set() + let view = View() + self.container.addSubview(view) - container.addSubview(view) - - view.snp_makeConstraints { (make) -> Void in - make.top.equalToSuperview().inset(10) - make.bottom.equalToSuperview().inset(10) + view.snp.remakeConstraints { (make) -> Void in + make.edges.equalTo(self.container.snp.margins) } - XCTAssertEqual(container.snp_constraints.count, 2, "Should have 2 constraints") + XCTAssertEqual(self.container.snp_constraints.count, 4, "Should have 4 constraints") - let constraints = container.snp_constraints as! [NSLayoutConstraint] - - XCTAssertEqual(constraints[0].firstAttribute, NSLayoutAttribute.Top, "Should be top") - XCTAssertEqual(constraints[1].firstAttribute, NSLayoutAttribute.Bottom, "Should be bottom") - - XCTAssertEqual(constraints[0].secondAttribute, NSLayoutAttribute.Top, "Should be top") - XCTAssertEqual(constraints[1].secondAttribute, NSLayoutAttribute.Bottom, "Should be bottom") - - XCTAssertEqual(constraints[0].firstItem as? View, view, "Should be added subview") - XCTAssertEqual(constraints[1].firstItem as? View, view, "Should be added subview") - - XCTAssertEqual(constraints[0].secondItem as? View, container, "Should be containerView") - XCTAssertEqual(constraints[1].secondItem as? View, container, "Should be containerView") - - XCTAssertEqual(constraints[0].constant, 10, "Should be 10") - XCTAssertEqual(constraints[1].constant, -10, "Should be 10") - } - - func testNativeConstraints() { - let view = View() - - container.addSubview(view) - - var topNativeConstraints: [LayoutConstraint]! - var topNativeConstraint: LayoutConstraint? - var sizeNativeConstraints: [LayoutConstraint]! - view.snp_makeConstraints { (make) -> Void in - let topConstraint = make.top.equalToSuperview().inset(10).constraint - topNativeConstraints = topConstraint.layoutConstraints - topNativeConstraint = topConstraint.layoutConstraints.first - let sizeConstraints = make.size.equalTo(50).constraint - sizeNativeConstraints = sizeConstraints.layoutConstraints + for constraint in (container.snp_constraints as! [NSLayoutConstraint]) { + fromAttributes.insert(constraint.firstAttribute) + toAttributes.insert(constraint.secondAttribute) } - - XCTAssertEqual(topNativeConstraints.count, 1, "make.top should creates one native constraint") - XCTAssertEqual(topNativeConstraint?.constant, 10, "topNativeConstraint.constant is set to 10") - XCTAssertEqual(sizeNativeConstraints.count, 2, "make.tosize should create two native constraint") - XCTAssertEqual(sizeNativeConstraints[0].constant, 50, "sizeNativeConstraints should set size[0] to 50") - XCTAssertEqual(sizeNativeConstraints[1].constant, 50, "sizeNativeConstraints should set size[1] to 50") + + XCTAssert(fromAttributes == [.top, .left, .bottom, .right]) + XCTAssert(toAttributes == [.topMargin, .leftMargin, .bottomMargin, .rightMargin]) + + fromAttributes.removeAll() + toAttributes.removeAll() + + view.snp.remakeConstraints { (make) -> Void in + make.margins.equalTo(self.container.snp.edges) + } + + XCTAssertEqual(self.container.snp_constraints.count, 4, "Should have 4 constraints") + + for constraint in (container.snp_constraints as! [NSLayoutConstraint]) { + fromAttributes.insert(constraint.firstAttribute) + toAttributes.insert(constraint.secondAttribute) + } + + XCTAssert(toAttributes == [.top, .left, .bottom, .right]) + XCTAssert(fromAttributes == [.topMargin, .leftMargin, .bottomMargin, .rightMargin]) + } + + func testEdgesToEdges() { + var fromAttributes = Set() + var toAttributes = Set() + + let view = View() + self.container.addSubview(view) + + view.snp.remakeConstraints { (make) -> Void in + make.edges.equalTo(self.container.snp.edges) + } + + XCTAssertEqual(self.container.snp_constraints.count, 4, "Should have 4 constraints") + + for constraint in (container.snp_constraints as! [NSLayoutConstraint]) { + fromAttributes.insert(constraint.firstAttribute) + toAttributes.insert(constraint.secondAttribute) + } + + XCTAssert(fromAttributes == [.top, .left, .bottom, .right]) + XCTAssert(toAttributes == [.top, .left, .bottom, .right]) + } + + func testLayoutGuideConstraints() { + let vc = UIViewController() + vc.view = UIView(frame: CGRect(x: 0, y: 0, width: 300, height: 300)) + + vc.view.addSubview(self.container) + + self.container.snp.makeConstraints { (make) -> Void in + make.top.equalTo(vc.topLayoutGuide.snp.bottom) + make.bottom.equalTo(vc.bottomLayoutGuide.snp.top) + } + + XCTAssertEqual(vc.view.snp_constraints.count, 6, "Should have 6 constraints installed") + } + #endif + }