mirror of https://github.com/SnapKit/SnapKit
Merge branch 'feature/0.40.0' of github.com:SnapKit/SnapKit into develop
# Conflicts: # .travis.yml # CHANGELOG.md # README.md # SnapKit.podspec # SnapKit.xcodeproj/project.pbxproj # SnapKit.xcodeproj/xcshareddata/xcschemes/SnapKit OSX.xcscheme # SnapKit.xcodeproj/xcshareddata/xcschemes/SnapKit iOS.xcscheme # Source/Constraint.swift # Source/ConstraintAttributes.swift # Source/ConstraintDescription.swift # Source/ConstraintMaker.swift # Source/ConstraintView.swift # Source/Debugging.swift # Source/LayoutConstraint.swift # Source/View+SnapKit.swift # Tests/Tests.swift
This commit is contained in:
commit
f03dd0e85f
19
.travis.yml
19
.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
|
||||
|
|
26
CHANGELOG.md
26
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 contentHugging<Axis>Priority: CGFloat` to `make`
|
||||
* Added `var contentCompressionResistance<Axis>Priority: 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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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'
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,113 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0800"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "EECDB3791AC0C9D4006BBC11"
|
||||
BuildableName = "SnapKit.framework"
|
||||
BlueprintName = "SnapKit OSX"
|
||||
ReferencedContainer = "container:SnapKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "NO"
|
||||
buildForProfiling = "NO"
|
||||
buildForArchiving = "NO"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "EECDB3831AC0C9D4006BBC11"
|
||||
BuildableName = "SnapKit OSX Tests.xctest"
|
||||
BlueprintName = "SnapKit OSX Tests"
|
||||
ReferencedContainer = "container:SnapKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "EECDB3831AC0C9D4006BBC11"
|
||||
BuildableName = "SnapKit OSX Tests.xctest"
|
||||
BlueprintName = "SnapKit OSX Tests"
|
||||
ReferencedContainer = "container:SnapKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "EECDB3791AC0C9D4006BBC11"
|
||||
BuildableName = "SnapKit.framework"
|
||||
BlueprintName = "SnapKit OSX"
|
||||
ReferencedContainer = "container:SnapKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "EECDB3791AC0C9D4006BBC11"
|
||||
BuildableName = "SnapKit.framework"
|
||||
BlueprintName = "SnapKit OSX"
|
||||
ReferencedContainer = "container:SnapKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "EECDB3791AC0C9D4006BBC11"
|
||||
BuildableName = "SnapKit.framework"
|
||||
BlueprintName = "SnapKit OSX"
|
||||
ReferencedContainer = "container:SnapKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
|
@ -0,0 +1,56 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0800"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "EEBCC9E119CC627D0083B827"
|
||||
BuildableName = "SnapKit Tests.xctest"
|
||||
BlueprintName = "SnapKit Tests"
|
||||
ReferencedContainer = "container:SnapKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
|
@ -1,113 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0800"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "537DCE911C35CC8800B5B899"
|
||||
BuildableName = "SnapKit.framework"
|
||||
BlueprintName = "SnapKit tvOS"
|
||||
ReferencedContainer = "container:SnapKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "NO"
|
||||
buildForProfiling = "NO"
|
||||
buildForArchiving = "NO"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "537DCEAE1C35D90A00B5B899"
|
||||
BuildableName = "SnapKit tvOS Tests.xctest"
|
||||
BlueprintName = "SnapKit tvOS Tests"
|
||||
ReferencedContainer = "container:SnapKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "537DCEAE1C35D90A00B5B899"
|
||||
BuildableName = "SnapKit tvOS Tests.xctest"
|
||||
BlueprintName = "SnapKit tvOS Tests"
|
||||
ReferencedContainer = "container:SnapKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "537DCE911C35CC8800B5B899"
|
||||
BuildableName = "SnapKit.framework"
|
||||
BlueprintName = "SnapKit tvOS"
|
||||
ReferencedContainer = "container:SnapKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "537DCE911C35CC8800B5B899"
|
||||
BuildableName = "SnapKit.framework"
|
||||
BlueprintName = "SnapKit tvOS"
|
||||
ReferencedContainer = "container:SnapKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "537DCE911C35CC8800B5B899"
|
||||
BuildableName = "SnapKit.framework"
|
||||
BlueprintName = "SnapKit tvOS"
|
||||
ReferencedContainer = "container:SnapKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
|
@ -16,7 +16,7 @@
|
|||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "EEBCC9D719CC627D0083B827"
|
||||
BuildableName = "SnapKit.framework"
|
||||
BlueprintName = "SnapKit iOS"
|
||||
BlueprintName = "SnapKit"
|
||||
ReferencedContainer = "container:SnapKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
|
@ -28,9 +28,9 @@
|
|||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "EEBCC9E119CC627D0083B827"
|
||||
BuildableName = "SnapKit iOS Tests.xctest"
|
||||
BlueprintName = "SnapKit iOS Tests"
|
||||
BlueprintIdentifier = "537DCEAE1C35D90A00B5B899"
|
||||
BuildableName = "SnapKit tvOS Tests.xctest"
|
||||
BlueprintName = "SnapKit tvOS Tests"
|
||||
ReferencedContainer = "container:SnapKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
|
@ -47,8 +47,8 @@
|
|||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "EEBCC9E119CC627D0083B827"
|
||||
BuildableName = "SnapKit iOS Tests.xctest"
|
||||
BlueprintName = "SnapKit iOS Tests"
|
||||
BuildableName = "SnapKit Tests.xctest"
|
||||
BlueprintName = "SnapKit Tests"
|
||||
ReferencedContainer = "container:SnapKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
|
@ -58,7 +58,7 @@
|
|||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "EEBCC9D719CC627D0083B827"
|
||||
BuildableName = "SnapKit.framework"
|
||||
BlueprintName = "SnapKit iOS"
|
||||
BlueprintName = "SnapKit"
|
||||
ReferencedContainer = "container:SnapKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
|
@ -80,7 +80,7 @@
|
|||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "EEBCC9D719CC627D0083B827"
|
||||
BuildableName = "SnapKit.framework"
|
||||
BlueprintName = "SnapKit iOS"
|
||||
BlueprintName = "SnapKit"
|
||||
ReferencedContainer = "container:SnapKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
|
@ -98,7 +98,7 @@
|
|||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "EEBCC9D719CC627D0083B827"
|
||||
BuildableName = "SnapKit.framework"
|
||||
BlueprintName = "SnapKit iOS"
|
||||
BlueprintName = "SnapKit"
|
||||
ReferencedContainer = "container:SnapKit.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
|
@ -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<View>()
|
||||
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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
||||
}
|
|
@ -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!
|
||||
}
|
||||
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
|
||||
}
|
|
@ -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 {
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
|
@ -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<LayoutConstraint> {
|
||||
let layoutConstraints: NSHashTable<LayoutConstraint>
|
||||
|
||||
if let existing = objc_getAssociatedObject(self.view, &layoutConstraintsKey) as? NSHashTable<LayoutConstraint> {
|
||||
layoutConstraints = existing
|
||||
} else {
|
||||
layoutConstraints = NSHashTable<LayoutConstraint>.weakObjects()
|
||||
objc_setAssociatedObject(self.view, &layoutConstraintsKey, layoutConstraints, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
|
||||
}
|
||||
return layoutConstraints
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
private var layoutConstraintsKey: UInt8 = 0
|
|
@ -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<T>(from object: Optional<T>) -> Optional<T> {
|
||||
return object
|
||||
}
|
||||
|
||||
private func conditionalOptional<T>(from object: T) -> Optional<T> {
|
||||
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
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
|
||||
}
|
|
@ -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 = ""
|
|
@ -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<NSLayoutAttribute>()
|
||||
var toAttributes = Set<NSLayoutAttribute>()
|
||||
|
||||
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<NSLayoutAttribute>()
|
||||
var toAttributes = Set<NSLayoutAttribute>()
|
||||
|
||||
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
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue