API updates, migrate away from iOS 7.0 support

This commit is contained in:
Robert Payne 2016-08-06 22:38:02 +12:00
parent 17a01931db
commit 9d0232ca08
14 changed files with 608 additions and 434 deletions

View File

@ -507,6 +507,7 @@
EEBCC9E119CC627D0083B827 = {
CreatedOnToolsVersion = 6.0;
LastSwiftMigration = 0800;
ProvisioningStyle = Automatic;
};
EECDB3791AC0C9D4006BBC11 = {
CreatedOnToolsVersion = 6.2;
@ -945,7 +946,8 @@
EEBCC9EC19CC627E0083B827 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = "$(SRCROOT)/Tests/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "io.snapkit.$(PRODUCT_NAME:rfc1034identifier)";
@ -957,7 +959,8 @@
EEBCC9ED19CC627E0083B827 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = "$(SRCROOT)/Tests/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "io.snapkit.$(PRODUCT_NAME:rfc1034identifier)";

View File

@ -27,10 +27,10 @@
import AppKit
#endif
public class Constraint {
internal let sourceLocation: (String, UInt)
internal let label: String?
private let from: ConstraintItem
private let to: ConstraintItem
@ -46,7 +46,7 @@ public class Constraint {
self.updateConstantAndPriorityIfNeeded()
}
}
private var installInfo: ConstraintInstallInfo? = nil
private let layoutConstraints: NSHashTable<LayoutConstraint>
// MARK: Initialization
@ -54,6 +54,7 @@ public class Constraint {
to: ConstraintItem,
relation: ConstraintRelation,
sourceLocation: (String, UInt),
label: String?,
multiplier: ConstraintMultiplierTarget,
constant: ConstraintConstantTarget,
priority: ConstraintPriorityTarget) {
@ -61,27 +62,67 @@ public class Constraint {
self.to = to
self.relation = relation
self.sourceLocation = sourceLocation
self.label = label
self.multiplier = multiplier
self.constant = constant
self.priority = priority
self.layoutConstraints = NSHashTable<LayoutConstraint>.weakObjects()
// get attributes
let layoutFromAttributes = self.from.attributes.layoutAttributes
let layoutToAttributes = self.to.attributes.layoutAttributes
// get layout from
let layoutFrom: ConstraintView = self.from.view!
// get relation
let layoutRelation = self.relation.layoutRelation
for layoutFromAttribute in layoutFromAttributes {
// get layout to attribute
let layoutToAttribute = (layoutToAttributes.count > 0) ? layoutToAttributes[0] : layoutFromAttribute
// get layout constant
let layoutConstant: CGFloat = self.constant.constraintConstantTargetValueFor(layoutAttribute: layoutToAttribute)
// get layout to
#if os(iOS) || os(tvOS)
let layoutTo: AnyObject? = self.to.view ?? self.to.layoutSupport
#else
let layoutTo: AnyObject? = self.to.view
#endif
// create layout constraint
let layoutConstraint = LayoutConstraint(
item: layoutFrom,
attribute: layoutFromAttribute,
relatedBy: layoutRelation,
toItem: layoutTo,
attribute: layoutToAttribute,
multiplier: self.multiplier.constraintMultiplierTargetValue,
constant: layoutConstant
)
// set label
layoutConstraint.label = self.label
// set priority
layoutConstraint.priority = self.priority.constraintPriorityTargetValue
// set constraint
layoutConstraint.constraint = self
// append
self.layoutConstraints.add(layoutConstraint)
}
}
// MARK: Public
public func install() -> [NSLayoutConstraint] {
return self.installIfNeeded(updateExisting: false)
}
public func uninstall() {
self.uninstallIfNeeded()
}
@available(iOS 8.0, OSX 10.10, *)
public func activate() {
self.activateIfNeeded()
}
@available(iOS 8.0, OSX 10.10, *)
public func deactivate() {
self.deactivateIfNeeded()
}
@ -128,248 +169,55 @@ public class Constraint {
// MARK: Internal
internal func updateConstantAndPriorityIfNeeded() {
guard let installInfo = self.installInfo else {
return
}
for layoutConstraint in installInfo.layoutConstraints.allObjects as! [LayoutConstraint] {
for layoutConstraint in self.layoutConstraints.allObjects {
let attribute = (layoutConstraint.secondAttribute == .notAnAttribute) ? layoutConstraint.firstAttribute : layoutConstraint.secondAttribute
layoutConstraint.constant = self.constant.constraintConstantTargetValueFor(layoutAttribute: attribute)
layoutConstraint.priority = self.priority.constraintPriorityTargetValue
}
}
internal func installIfNeeded(updateExisting: Bool = false) -> [NSLayoutConstraint] {
let installOnView: ConstraintView?
internal func activateIfNeeded(updatingExisting: Bool = false) {
let view = self.from.view!
let layoutConstraints = self.layoutConstraints.allObjects
let existingLayoutConstraints = view.snp.layoutConstraints
if let view = self.to.view {
guard let closestSuperview = closestCommonSuperviewFromView(self.from.view, toView: view) else {
fatalError("Cannot Install Constraint. No common superview. (\(self.sourceLocation.0), \(self.sourceLocation.1))")
if updatingExisting && existingLayoutConstraints.count > 0 {
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)")
}
let updateLayoutAttribute = (updateLayoutConstraint.secondAttribute == .notAnAttribute) ? updateLayoutConstraint.firstAttribute : updateLayoutConstraint.secondAttribute
updateLayoutConstraint.constant = self.constant.constraintConstantTargetValueFor(layoutAttribute: updateLayoutAttribute)
}
installOnView = closestSuperview
} else if self.from.attributes.isSubset(of: ConstraintAttributes.Width + ConstraintAttributes.Height) {
installOnView = self.from.view
} else {
guard let superview = self.from.view?.superview else {
fatalError("Cannot Install Constraint. No superview. (\(self.sourceLocation.0), \(self.sourceLocation.1))")
}
installOnView = superview
NSLayoutConstraint.activate(layoutConstraints)
view.snp.add(layoutConstraints: layoutConstraints)
}
guard self.installInfo?.view == nil ||
self.installInfo?.view == installOnView else {
fatalError("Cannot Install Constraint. Already installed on different view. (\(self.sourceLocation.0), \(self.sourceLocation.1))")
}
// setup array to store new layout constraints
var newLayoutConstraints = [LayoutConstraint]()
// get attributes
let layoutFromAttributes = self.from.attributes.layoutAttributes
let layoutToAttributes = self.to.attributes.layoutAttributes
// get layout from
let layoutFrom: ConstraintView = self.from.view!
// get relation
let layoutRelation = self.relation.layoutRelation
for layoutFromAttribute in layoutFromAttributes {
// get layout to attribute
let layoutToAttribute = (layoutToAttributes.count > 0) ? layoutToAttributes[0] : layoutFromAttribute
// get layout constant
let layoutConstant: CGFloat = self.constant.constraintConstantTargetValueFor(layoutAttribute: layoutToAttribute)
// get layout to
#if os(iOS) || os(tvOS)
var layoutTo: AnyObject? = self.to.view ?? self.to.layoutSupport
#else
var layoutTo: AnyObject? = self.to.view
#endif
if layoutTo == nil && layoutToAttribute != .width && layoutToAttribute != .height {
layoutTo = installOnView
}
// create layout constraint
let layoutConstraint = LayoutConstraint(
item: layoutFrom,
attribute: layoutFromAttribute,
relatedBy: layoutRelation,
toItem: layoutTo,
attribute: layoutToAttribute,
multiplier: self.multiplier.constraintMultiplierTargetValue,
constant: layoutConstant
)
// set priority
layoutConstraint.priority = self.priority.constraintPriorityTargetValue
// set constraint
layoutConstraint.constraint = self
// append
newLayoutConstraints.append(layoutConstraint)
}
// updating logic
if updateExisting {
// get existing constraints for this view
let existingLayoutConstraints = layoutFrom.snp.installedLayoutConstraints.reversed()
// 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 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)
}
}
// set constraints to only new ones
newLayoutConstraints = newLayoutConstraintsToKeep
}
// add constraints
#if SNAPKIT_DEPLOYMENT_LEGACY && (os(iOS) || os(tvOS))
if #available(iOS 8.0, *) {
NSLayoutConstraint.activate(newLayoutConstraints)
} else {
installOnView?.addConstraints(newLayoutConstraints)
}
#else
NSLayoutConstraint.activate(newLayoutConstraints)
#endif
// set install info
self.installInfo = ConstraintInstallInfo(view: installOnView, layoutConstraints: NSHashTable.weakObjects())
// store which layout constraints are installed for this constraint
for layoutConstraint in newLayoutConstraints {
self.installInfo!.layoutConstraints.add(layoutConstraint)
}
// store the layout constraints against the layout from view
layoutFrom.snp.appendInstalledLayoutConstraints(newLayoutConstraints)
return newLayoutConstraints
}
internal func uninstallIfNeeded() {
defer {
self.installInfo = nil
}
guard let installedLayoutConstraints = self.installInfo?.layoutConstraints.allObjects as? [LayoutConstraint],
installedLayoutConstraints.count > 0 else {
return
}
#if SNAPKIT_DEPLOYMENT_LEGACY && !os(OSX)
if #available(iOS 8.0, *) {
NSLayoutConstraint.deactivate(installedLayoutConstraints)
} else if let installedOnView = installInfo?.view {
installedOnView.removeConstraints(installedLayoutConstraints)
}
#else
NSLayoutConstraint.deactivate(installedLayoutConstraints)
#endif
// remove the constraints from the from item view
self.from.view?.snp.removeInstalledLayoutConstraints(installedLayoutConstraints)
}
internal func activateIfNeeded() {
guard self.installInfo != nil else {
_ = self.installIfNeeded()
return
}
#if SNAPKIT_DEPLOYMENT_LEGACY
guard #available(iOS 8.0, OSX 10.10, *) else {
_ = self.installIfNeeded()
return
}
#endif
guard let layoutConstraints = self.installInfo?.layoutConstraints.allObjects as? [LayoutConstraint],
layoutConstraints.count > 0 else {
return
}
NSLayoutConstraint.activate(layoutConstraints)
print(view, layoutConstraints.count, existingLayoutConstraints.count)
}
internal func deactivateIfNeeded() {
#if SNAPKIT_DEPLOYMENT_LEGACY
guard #available(iOS 8.0, OSX 10.10, *) else {
return
}
#endif
guard let layoutConstraints = self.installInfo?.layoutConstraints.allObjects as? [LayoutConstraint],
layoutConstraints.count > 0 else {
return
}
let view = self.from.view!
let layoutConstraints = self.layoutConstraints.allObjects
NSLayoutConstraint.deactivate(layoutConstraints)
view.snp.remove(layoutConstraints: layoutConstraints)
}
}
extension Constraint: Hashable {
public var hashValue: Int {
return self.layoutConstraints.hashValue
}
}
private final class ConstraintInstallInfo {
private weak var view: ConstraintView? = nil
private let layoutConstraints: NSHashTable<AnyObject>
private init(view: ConstraintView?, layoutConstraints: NSHashTable<AnyObject>) {
self.view = view
self.layoutConstraints = layoutConstraints
}
}
private func closestCommonSuperviewFromView(_ fromView: ConstraintView?, toView: ConstraintView?) -> ConstraintView? {
var views = Set<ConstraintView>()
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 ==(lhs: Constraint, rhs: Constraint) -> Bool {
public func ==(lhs: Constraint, rhs: Constraint) -> Bool {
return (lhs.from == rhs.from &&
lhs.to == rhs.to &&
lhs.relation == rhs.relation &&

View File

@ -51,117 +51,120 @@ internal struct ConstraintAttributes: OptionSet {
// 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)) {
if (self.contains(ConstraintAttributes.left)) {
attrs.append(.left)
}
if (self.contains(ConstraintAttributes.Top)) {
if (self.contains(ConstraintAttributes.top)) {
attrs.append(.top)
}
if (self.contains(ConstraintAttributes.Right)) {
if (self.contains(ConstraintAttributes.right)) {
attrs.append(.right)
}
if (self.contains(ConstraintAttributes.Bottom)) {
if (self.contains(ConstraintAttributes.bottom)) {
attrs.append(.bottom)
}
if (self.contains(ConstraintAttributes.Leading)) {
if (self.contains(ConstraintAttributes.leading)) {
attrs.append(.leading)
}
if (self.contains(ConstraintAttributes.Trailing)) {
if (self.contains(ConstraintAttributes.trailing)) {
attrs.append(.trailing)
}
if (self.contains(ConstraintAttributes.Width)) {
if (self.contains(ConstraintAttributes.width)) {
attrs.append(.width)
}
if (self.contains(ConstraintAttributes.Height)) {
if (self.contains(ConstraintAttributes.height)) {
attrs.append(.height)
}
if (self.contains(ConstraintAttributes.CenterX)) {
if (self.contains(ConstraintAttributes.centerX)) {
attrs.append(.centerX)
}
if (self.contains(ConstraintAttributes.CenterY)) {
if (self.contains(ConstraintAttributes.centerY)) {
attrs.append(.centerY)
}
if (self.contains(ConstraintAttributes.Baseline)) {
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)) {
if (self.contains(ConstraintAttributes.firstBaseline)) {
attrs.append(.firstBaseline)
}
if (self.contains(ConstraintAttributes.LeftMargin)) {
if (self.contains(ConstraintAttributes.leftMargin)) {
attrs.append(.leftMargin)
}
if (self.contains(ConstraintAttributes.RightMargin)) {
if (self.contains(ConstraintAttributes.rightMargin)) {
attrs.append(.rightMargin)
}
if (self.contains(ConstraintAttributes.TopMargin)) {
if (self.contains(ConstraintAttributes.topMargin)) {
attrs.append(.topMargin)
}
if (self.contains(ConstraintAttributes.BottomMargin)) {
if (self.contains(ConstraintAttributes.bottomMargin)) {
attrs.append(.bottomMargin)
}
if (self.contains(ConstraintAttributes.LeadingMargin)) {
if (self.contains(ConstraintAttributes.leadingMargin)) {
attrs.append(.leadingMargin)
}
if (self.contains(ConstraintAttributes.TrailingMargin)) {
if (self.contains(ConstraintAttributes.trailingMargin)) {
attrs.append(.trailingMargin)
}
if (self.contains(ConstraintAttributes.CenterXWithinMargins)) {
if (self.contains(ConstraintAttributes.centerXWithinMargins)) {
attrs.append(.centerXWithinMargins)
}
if (self.contains(ConstraintAttributes.CenterYWithinMargins)) {
if (self.contains(ConstraintAttributes.centerYWithinMargins)) {
attrs.append(.centerYWithinMargins)
}
#endif

View File

@ -34,6 +34,7 @@ public class ConstraintDescription {
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
@ -51,6 +52,7 @@ public class ConstraintDescription {
to: related,
relation: relation,
sourceLocation: sourceLocation,
label: self.label,
multiplier: self.multiplier,
constant: self.constant,
priority: self.priority

View File

@ -30,95 +30,109 @@
public class ConstraintMaker {
public var left: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(ConstraintAttributes.Left)
return self.makeExtendableWithAttributes(.left)
}
public var top: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(ConstraintAttributes.Top)
return self.makeExtendableWithAttributes(.top)
}
public var bottom: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(ConstraintAttributes.Bottom)
return self.makeExtendableWithAttributes(.bottom)
}
public var right: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(ConstraintAttributes.Right)
return self.makeExtendableWithAttributes(.right)
}
public var leading: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(ConstraintAttributes.Leading)
return self.makeExtendableWithAttributes(.leading)
}
public var trailing: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(ConstraintAttributes.Trailing)
return self.makeExtendableWithAttributes(.trailing)
}
public var width: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(ConstraintAttributes.Width)
return self.makeExtendableWithAttributes(.width)
}
public var height: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(ConstraintAttributes.Height)
return self.makeExtendableWithAttributes(.height)
}
public var centerX: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(ConstraintAttributes.CenterX)
}
public var centerY: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(ConstraintAttributes.CenterY)
}
public var baseline: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(ConstraintAttributes.Baseline)
return self.makeExtendableWithAttributes(.centerX)
}
@available(iOS 8.0, *)
public var centerY: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(.centerY)
}
@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(ConstraintAttributes.FirstBaseline)
return self.makeExtendableWithAttributes(.firstBaseline)
}
@available(iOS 8.0, *)
public var leftMargin: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(ConstraintAttributes.LeftMargin)
return self.makeExtendableWithAttributes(.leftMargin)
}
@available(iOS 8.0, *)
public var rightMargin: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(ConstraintAttributes.RightMargin)
return self.makeExtendableWithAttributes(.rightMargin)
}
@available(iOS 8.0, *)
public var bottomMargin: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(ConstraintAttributes.BottomMargin)
return self.makeExtendableWithAttributes(.bottomMargin)
}
@available(iOS 8.0, *)
public var leadingMargin: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(ConstraintAttributes.LeadingMargin)
return self.makeExtendableWithAttributes(.leadingMargin)
}
@available(iOS 8.0, *)
public var trailingMargin: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(ConstraintAttributes.TrailingMargin)
return self.makeExtendableWithAttributes(.trailingMargin)
}
@available(iOS 8.0, *)
public var centerXWithinMargins: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(ConstraintAttributes.CenterXWithinMargins)
return self.makeExtendableWithAttributes(.centerXWithinMargins)
}
@available(iOS 8.0, *)
public var centerYWithinMargins: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(ConstraintAttributes.CenterYWithinMargins)
return self.makeExtendableWithAttributes(.centerYWithinMargins)
}
public var edges: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(ConstraintAttributes.Edges)
return self.makeExtendableWithAttributes(.edges)
}
public var size: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(ConstraintAttributes.Size)
return self.makeExtendableWithAttributes(.size)
}
@available(iOS 8.0, *)
public var margins: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(ConstraintAttributes.Margins)
return self.makeExtendableWithAttributes(.margins)
}
@available(iOS 8.0, *)
public var centerWithinMargins: ConstraintMakerExtendable {
return self.makeExtendableWithAttributes(ConstraintAttributes.CenterWithinMargins)
return self.makeExtendableWithAttributes(.centerWithinMargins)
}
private let view: ConstraintView
@ -153,7 +167,7 @@ public class ConstraintMaker {
.filter { $0 != nil }
.map { $0! }
for constraint in constraints {
let _ = constraint.installIfNeeded()
constraint.activateIfNeeded(updatingExisting: false)
}
}
@ -170,13 +184,14 @@ public class ConstraintMaker {
.filter { $0 != nil }
.map { $0! }
for constraint in constraints {
let _ = constraint.installIfNeeded(updateExisting: true)
constraint.activateIfNeeded(updatingExisting: true)
}
}
internal static func removeConstraints(view: ConstraintView) {
for layoutConstraint in view.snp.installedLayoutConstraints {
layoutConstraint.constraint?.uninstall()
let constraints = view.snp.layoutConstraints.map { $0.constraint! }
for constraint in constraints {
constraint.deactivateIfNeeded()
}
}

View File

@ -31,126 +31,132 @@
public class ConstraintMakerExtendable: ConstraintMakerRelatable {
public var left: ConstraintMakerExtendable {
self.description.attributes += ConstraintAttributes.Left
self.description.attributes += .left
return self
}
public var top: ConstraintMakerExtendable {
self.description.attributes += ConstraintAttributes.Top
self.description.attributes += .top
return self
}
public var bottom: ConstraintMakerExtendable {
self.description.attributes += ConstraintAttributes.Bottom
self.description.attributes += .bottom
return self
}
public var right: ConstraintMakerExtendable {
self.description.attributes += ConstraintAttributes.Right
self.description.attributes += .right
return self
}
public var leading: ConstraintMakerExtendable {
self.description.attributes += ConstraintAttributes.Leading
self.description.attributes += .leading
return self
}
public var trailing: ConstraintMakerExtendable {
self.description.attributes += ConstraintAttributes.Trailing
self.description.attributes += .trailing
return self
}
public var width: ConstraintMakerExtendable {
self.description.attributes += ConstraintAttributes.Width
self.description.attributes += .width
return self
}
public var height: ConstraintMakerExtendable {
self.description.attributes += ConstraintAttributes.Height
self.description.attributes += .height
return self
}
public var centerX: ConstraintMakerExtendable {
self.description.attributes += ConstraintAttributes.CenterX
self.description.attributes += .centerX
return self
}
public var centerY: ConstraintMakerExtendable {
self.description.attributes += ConstraintAttributes.CenterY
self.description.attributes += .centerY
return self
}
@available(*, deprecated:0.40.0, message:"Use lastBaseline instead")
public var baseline: ConstraintMakerExtendable {
self.description.attributes += ConstraintAttributes.Baseline
self.description.attributes += .lastBaseline
return self
}
@available(iOS 8.0, *)
public var lastBaseline: ConstraintMakerExtendable {
self.description.attributes += .lastBaseline
return self
}
@available(iOS 8.0, OSX 10.11, *)
public var firstBaseline: ConstraintMakerExtendable {
self.description.attributes += ConstraintAttributes.FirstBaseline
self.description.attributes += .firstBaseline
return self
}
@available(iOS 8.0, *)
public var leftMargin: ConstraintMakerExtendable {
self.description.attributes += ConstraintAttributes.LeftMargin
self.description.attributes += .leftMargin
return self
}
@available(iOS 8.0, *)
public var rightMargin: ConstraintMakerExtendable {
self.description.attributes += ConstraintAttributes.RightMargin
self.description.attributes += .rightMargin
return self
}
@available(iOS 8.0, *)
public var bottomMargin: ConstraintMakerExtendable {
self.description.attributes += ConstraintAttributes.BottomMargin
self.description.attributes += .bottomMargin
return self
}
@available(iOS 8.0, *)
public var leadingMargin: ConstraintMakerExtendable {
self.description.attributes += ConstraintAttributes.LeadingMargin
self.description.attributes += .leadingMargin
return self
}
@available(iOS 8.0, *)
public var trailingMargin: ConstraintMakerExtendable {
self.description.attributes += ConstraintAttributes.TrailingMargin
self.description.attributes += .trailingMargin
return self
}
@available(iOS 8.0, *)
public var centerXWithinMargins: ConstraintMakerExtendable {
self.description.attributes += ConstraintAttributes.CenterXWithinMargins
self.description.attributes += .centerXWithinMargins
return self
}
@available(iOS 8.0, *)
public var centerYWithinMargins: ConstraintMakerExtendable {
self.description.attributes += ConstraintAttributes.CenterYWithinMargins
self.description.attributes += .centerYWithinMargins
return self
}
public var edges: ConstraintMakerExtendable {
self.description.attributes += ConstraintAttributes.Edges
self.description.attributes += .edges
return self
}
public var size: ConstraintMakerExtendable {
self.description.attributes += ConstraintAttributes.Size
self.description.attributes += .size
return self
}
@available(iOS 8.0, *)
public var margins: ConstraintMakerExtendable {
self.description.attributes += ConstraintAttributes.Margins
self.description.attributes += .margins
return self
}
@available(iOS 8.0, *)
public var centerWithinMargins: ConstraintMakerExtendable {
self.description.attributes += ConstraintAttributes.CenterWithinMargins
self.description.attributes += .centerWithinMargins
return self
}

View File

@ -36,6 +36,12 @@ public class ConstraintMakerFinalizable {
self.description = description
}
@discardableResult
public func labeled(_ label: String) -> ConstraintMakerFinalizable {
self.description.label = label
return self
}
public var constraint: Constraint {
return self.description.constraint!
}

View File

@ -41,7 +41,7 @@ public class ConstraintMakerRelatable {
let constant: ConstraintConstantTarget
if let other = other as? ConstraintItem {
guard other.attributes == ConstraintAttributes.None ||
guard other.attributes == ConstraintAttributes.none ||
other.attributes.layoutAttributes.count <= 1 ||
other.attributes.layoutAttributes == self.description.attributes.layoutAttributes else {
fatalError("Cannot constraint to multiple non identical attributes. (\(file), \(line))");
@ -50,10 +50,10 @@ public class ConstraintMakerRelatable {
related = other
constant = 0.0
} else if let other = other as? ConstraintView {
related = ConstraintItem(target: other, attributes: ConstraintAttributes.None)
related = ConstraintItem(target: other, attributes: ConstraintAttributes.none)
constant = 0.0
} else if let other = other as? ConstraintConstantTarget {
related = ConstraintItem(target: nil, attributes: ConstraintAttributes.None)
related = ConstraintItem(target: nil, attributes: ConstraintAttributes.none)
constant = other
} else {
fatalError("Invalid constraint. (\(file), \(line))")

View File

@ -30,117 +30,116 @@
public extension ConstraintView {
@available(*, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
@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:"Please use newer snp.* syntax.")
@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:"Please use newer snp.* syntax.")
@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:"Please use newer snp.* syntax.")
@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:"Please use newer snp.* syntax.")
@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:"Please use newer snp.* syntax.")
@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:"Please use newer snp.* syntax.")
@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:"Please use newer snp.* syntax.")
@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:"Please use newer snp.* syntax.")
@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:"Please use newer snp.* syntax.")
@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:"Please use newer snp.* syntax.")
@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:"Please use newer snp.* syntax.")
@available(iOS 8.0, OSX 10.11, *)
@available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.")
public var snp_lastBaseline: ConstraintItem { return self.snp.lastBaseline }
@available(iOS, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
@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:"Please use newer snp.* syntax.")
@available(iOS 8.0, OSX 10.11, *)
@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:"Please use newer snp.* syntax.")
@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:"Please use newer snp.* syntax.")
@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:"Please use newer snp.* syntax.")
@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:"Please use newer snp.* syntax.")
@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:"Please use newer snp.* syntax.")
@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:"Please use newer snp.* syntax.")
@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:"Please use newer snp.* syntax.")
@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:"Please use newer snp.* syntax.")
@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:"Please use newer snp.* syntax.")
@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:"Please use newer snp.* syntax.")
@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:"Please use newer snp.* syntax.")
@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:"Please use newer snp.* syntax.")
@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:"Please use newer snp.* syntax.")
@available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.")
public func snp_prepareConstraints(_ closure: @noescape(make: ConstraintMaker) -> Void) -> [Constraint] {
return self.snp.prepareConstraints(closure)
}
@available(*, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
@available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.")
public func snp_makeConstraints(_ closure: @noescape(make: ConstraintMaker) -> Void) {
self.snp.makeConstraints(closure)
}
@available(*, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
@available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.")
public func snp_remakeConstraints(_ closure: @noescape(make: ConstraintMaker) -> Void) {
self.snp.remakeConstraints(closure)
}
@available(*, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
@available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.")
public func snp_updateConstraints(_ closure: @noescape(make: ConstraintMaker) -> Void) {
self.snp.updateConstraints(closure)
}
@available(*, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
@available(*, deprecated:0.40.0, message:"Use newer snp.* syntax.")
public func snp_removeConstraints() {
self.snp.removeConstraints()
}

View File

@ -27,22 +27,22 @@
public extension ConstraintViewController {
@available(iOS, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
@available(iOS, deprecated:0.40.0, message:"Use newer snp.* syntax.")
public var topLayoutGuideTop: ConstraintItem {
return self.snp.topLayoutGuideTop
}
@available(iOS, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
@available(iOS, deprecated:0.40.0, message:"Use newer snp.* syntax.")
public var topLayoutGuideBottom: ConstraintItem {
return self.snp.topLayoutGuideBottom
}
@available(iOS, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
@available(iOS, deprecated:0.40.0, message:"Use newer snp.* syntax.")
public var bottomLayoutGuideTop: ConstraintItem {
return self.snp.bottomLayoutGuideTop
}
@available(iOS, deprecated:0.40.0, message:"Please use newer snp.* syntax.")
@available(iOS, deprecated:0.40.0, message:"Use newer snp.* syntax.")
public var bottomLayoutGuideBottom: ConstraintItem {
return self.snp.bottomLayoutGuideBottom
}

View File

@ -27,24 +27,24 @@
public struct ConstraintViewControllerDSL {
@available(iOS 7.0, *)
@available(iOS 8.0, *)
public var topLayoutGuideTop: ConstraintItem {
return ConstraintItem(target: self.viewController.topLayoutGuide, attributes: ConstraintAttributes.Top)
return ConstraintItem(target: self.viewController.topLayoutGuide, attributes: ConstraintAttributes.top)
}
@available(iOS 7.0, *)
@available(iOS 8.0, *)
public var topLayoutGuideBottom: ConstraintItem {
return ConstraintItem(target: self.viewController.topLayoutGuide, attributes: ConstraintAttributes.Bottom)
return ConstraintItem(target: self.viewController.topLayoutGuide, attributes: ConstraintAttributes.bottom)
}
@available(iOS 7.0, *)
@available(iOS 8.0, *)
public var bottomLayoutGuideTop: ConstraintItem {
return ConstraintItem(target: self.viewController.bottomLayoutGuide, attributes: ConstraintAttributes.Top)
return ConstraintItem(target: self.viewController.bottomLayoutGuide, attributes: ConstraintAttributes.top)
}
@available(iOS 7.0, *)
@available(iOS 8.0, *)
public var bottomLayoutGuideBottom: ConstraintItem {
return ConstraintItem(target: self.viewController.bottomLayoutGuide, attributes: ConstraintAttributes.Bottom)
return ConstraintItem(target: self.viewController.bottomLayoutGuide, attributes: ConstraintAttributes.bottom)
}
internal let viewController: ConstraintViewController

View File

@ -31,122 +31,123 @@
public struct ConstraintViewDSL {
public var left: ConstraintItem {
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.Left)
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.left)
}
public var top: ConstraintItem {
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.Top)
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.top)
}
public var right: ConstraintItem {
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.Right)
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.right)
}
public var bottom: ConstraintItem {
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.Bottom)
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.bottom)
}
public var leading: ConstraintItem {
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.Leading)
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.leading)
}
public var trailing: ConstraintItem {
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.Trailing)
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.trailing)
}
public var width: ConstraintItem {
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.Width)
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.width)
}
public var height: ConstraintItem {
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.Height)
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.height)
}
public var centerX: ConstraintItem {
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.CenterX)
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.centerX)
}
public var centerY: ConstraintItem {
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.CenterY)
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.centerY)
}
@available(*, deprecated:0.40.0, message:"Please use migrated .lastBaseline")
@available(*, deprecated:0.40.0, message:"Use .lastBaseline instead")
public var baseline: ConstraintItem {
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.Baseline)
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.lastBaseline)
}
@available(iOS 8.0, OSX 10.11, *)
public var lastBaseline: ConstraintItem {
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.Baseline)
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.lastBaseline)
}
@available(iOS 8.0, OSX 10.11, *)
public var firstBaseline: ConstraintItem {
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.FirstBaseline)
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.firstBaseline)
}
@available(iOS 8.0, *)
public var leftMargin: ConstraintItem {
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.LeftMargin)
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.leftMargin)
}
@available(iOS 8.0, *)
public var topMargin: ConstraintItem {
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.TopMargin)
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.topMargin)
}
@available(iOS 8.0, *)
public var rightMargin: ConstraintItem {
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.RightMargin)
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.rightMargin)
}
@available(iOS 8.0, *)
public var bottomMargin: ConstraintItem {
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.BottomMargin)
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.bottomMargin)
}
@available(iOS 8.0, *)
public var leadingMargin: ConstraintItem {
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.LeadingMargin)
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.leadingMargin)
}
@available(iOS 8.0, *)
public var trailingMargin: ConstraintItem {
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.TrailingMargin)
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.trailingMargin)
}
@available(iOS 8.0, *)
public var centerXWithinMargins: ConstraintItem {
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.CenterXWithinMargins)
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.centerXWithinMargins)
}
@available(iOS 8.0, *)
public var centerYWithinMargins: ConstraintItem {
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.CenterYWithinMargins)
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.centerYWithinMargins)
}
public var edges: ConstraintItem {
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.Edges)
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.edges)
}
public var size: ConstraintItem {
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.Size)
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.size)
}
public var center: ConstraintItem {
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.Center)
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.center)
}
@available(iOS 8.0, *)
public var margins: ConstraintItem {
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.Margins)
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.margins)
}
@available(iOS 8.0, *)
public var centerWithinMargins: ConstraintItem {
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.CenterWithinMargins)
return ConstraintItem(target: self.view, attributes: ConstraintAttributes.centerWithinMargins)
}
@discardableResult
public func prepareConstraints(_ closure: @noescape (make: ConstraintMaker) -> Void) -> [Constraint] {
return ConstraintMaker.prepareConstraints(view: self.view, closure: closure)
}
@ -216,23 +217,23 @@ public struct ConstraintViewDSL {
internal init(view: ConstraintView) {
self.view = view
}
internal var installedLayoutConstraints: [LayoutConstraint] {
return objc_getAssociatedObject(self.view, &installedLayoutConstraintsKey) as? [LayoutConstraint] ?? []
internal var layoutConstraints: [LayoutConstraint] {
return objc_getAssociatedObject(self.view, &layoutConstraintsKey) as? [LayoutConstraint] ?? []
}
internal func appendInstalledLayoutConstraints(_ layoutConstraints: [LayoutConstraint]) {
var newValue = self.installedLayoutConstraints
newValue += layoutConstraints
objc_setAssociatedObject(self.view, &installedLayoutConstraintsKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
internal func add(layoutConstraints: [LayoutConstraint]) {
let merged = self.layoutConstraints + layoutConstraints
objc_setAssociatedObject(self.view, &layoutConstraintsKey, merged, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
internal func removeInstalledLayoutConstraints(_ layoutConstraints: [LayoutConstraint]) {
let newValue = self.installedLayoutConstraints.filter { !layoutConstraints.contains($0) }
objc_setAssociatedObject(self.view, &installedLayoutConstraintsKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
internal func remove(layoutConstraints: [LayoutConstraint]) {
let merged = self.layoutConstraints.filter { !layoutConstraints.contains($0) }
objc_setAssociatedObject(self.view, &layoutConstraintsKey, merged, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
private var labelKey: UInt8 = 0
private var installedLayoutConstraintsKey: UInt8 = 0
private var layoutConstraintsKey: UInt8 = 0

View File

@ -30,8 +30,16 @@
public class LayoutConstraint: NSLayoutConstraint {
internal var constraint: Constraint? = nil
public var label: String? = nil
public var label: String? {
get {
return self.identifier
}
set {
self.identifier = newValue
}
}
internal var constraint: Constraint! = nil
}

View File

@ -13,7 +13,7 @@ extension View {
#endif
import XCTest
import SnapKit
@testable import SnapKit
class SnapKitTests: XCTestCase {
@ -29,4 +29,287 @@ class SnapKitTests: XCTestCase {
super.tearDown()
}
func testLayoutGuideConstraints() {
#if os(iOS) || os(tvOS)
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.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)
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)
print(v1)
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)
return
}
XCTAssertEqual(self.container.snp_constraints.count, 2, "Should still have 2 constraints installed")
}
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)
return
}
XCTAssertEqual(self.container.snp_constraints.count, 2, "Should have 2 constraints installed")
v1.snp.remakeConstraints { (make) -> Void in
make.edges.equalTo(v2)
return
}
XCTAssertEqual(self.container.snp_constraints.count, 4, "Should have 4 constraints installed")
}
func testRemoveConstraints() {
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)
return
}
XCTAssertEqual(self.container.snp_constraints.count, 2, "Should have 2 constraints installed")
v1.snp.removeConstraints()
XCTAssertEqual(self.container.snp_constraints.count, 0, "Should have 0 constraints installed")
}
func testPrepareConstraints() {
let v1 = View()
let v2 = View()
self.container.addSubview(v1)
self.container.addSubview(v2)
let constraints = v1.snp.prepareConstraints { (make) -> Void in
make.edges.equalTo(v2)
return
}
XCTAssertEqual(self.container.snp_constraints.count, 0, "Should have 0 constraints installed")
for constraint in constraints {
constraint.activate()
}
XCTAssertEqual(self.container.snp_constraints.count, 4, "Should have 4 constraints installed")
for constraint in constraints {
constraint.deactivate()
}
XCTAssertEqual(self.container.snp_constraints.count, 0, "Should have 0 constraints installed")
}
func testReactivateConstraints() {
let v1 = View()
let v2 = View()
self.container.addSubview(v1)
self.container.addSubview(v2)
let constraints = v1.snp.prepareConstraints { (make) -> Void in
make.edges.equalTo(v2)
return
}
XCTAssertEqual(self.container.snp_constraints.count, 0, "Should have 0 constraints installed")
for constraint in constraints {
constraint.activate()
}
XCTAssertEqual(self.container.snp_constraints.count, 4, "Should have 4 constraints installed")
for constraint in constraints {
constraint.deactivate()
}
XCTAssertEqual(self.container.snp_constraints.count, 0, "Should have 0 constraints installed")
}
func testActivateDeactivateConstraints() {
let v1 = View()
let v2 = View()
self.container.addSubview(v1)
self.container.addSubview(v2)
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
return
}
XCTAssertEqual(self.container.snp_constraints.count, 0, "Should have 0 constraints")
c1?.activate()
c2?.activate()
XCTAssertEqual(self.container.snp_constraints.count, 2, "Should have 2 constraints")
c1?.deactivate()
c2?.deactivate()
XCTAssertEqual(self.container.snp_constraints.count, 0, "Should have 0 constraints")
c1?.activate()
c2?.activate()
XCTAssertEqual(self.container.snp_constraints.count, 2, "Should have 2 constraints")
}
func testSizeConstraints() {
let view = View()
self.container.addSubview(view)
view.snp.makeConstraints { (make) -> Void in
make.size.equalTo(CGSize(width: 50, height: 50))
make.left.top.equalTo(self.container)
}
XCTAssertEqual(view.snp_constraints.count, 2, "Should have 2 constraints")
XCTAssertEqual(self.container.snp_constraints.count, 2, "Should have 2 constraints")
let constraints = view.snp_constraints as! [NSLayoutConstraint]
XCTAssertEqual(constraints[0].firstAttribute.rawValue, NSLayoutAttribute.width.rawValue, "Should be width")
XCTAssertEqual(constraints[1].firstAttribute.rawValue, NSLayoutAttribute.height.rawValue, "Should be height")
XCTAssertEqual(constraints[0].constant, 50, "Should be 50")
XCTAssertEqual(constraints[1].constant, 50, "Should be 50")
}
func testConstraintIdentifier() {
let identifier = "Test-Identifier"
let view = View()
self.container.addSubview(view)
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() {
//// let view = View()
////
//// container.addSubview(view)
////
//// view.snp.makeConstraints { (make) -> Void in
//// make.top.equalToSuperview().inset(10)
//// make.bottom.equalToSuperview().inset(10)
//// }
////
//// XCTAssertEqual(container.snp_constraints.count, 2, "Should have 2 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
//// }
////
//// 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")
//// }
}