From 8225dd363390ade0b40ad9e06e735d434eef3c12 Mon Sep 17 00:00:00 2001 From: Orkhan Alikhanov Date: Wed, 22 May 2019 18:35:52 +0400 Subject: [PATCH 1/3] Added layout relation --- Sources/iOS/Layout/Layout.swift | 3 ++- Sources/iOS/Layout/LayoutConstraint.swift | 17 +++++++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Sources/iOS/Layout/Layout.swift b/Sources/iOS/Layout/Layout.swift index 1342141b5..ee9c446a2 100644 --- a/Sources/iOS/Layout/Layout.swift +++ b/Sources/iOS/Layout/Layout.swift @@ -83,6 +83,7 @@ private extension NSLayoutConstraint { && secondItem === other.secondItem && firstAttribute == other.firstAttribute && secondAttribute == other.secondAttribute + && relation == other.relation } } @@ -1121,7 +1122,7 @@ private extension Layout { let v = (anchor as? UIView) ?? (anchor as? LayoutAnchor)?.constraintable to = LayoutAnchor(constraintable: v, attributes: attributes) } - let constraint = LayoutConstraint(fromAnchor: from, toAnchor: to!, constants: constants) + let constraint = LayoutConstraint(fromAnchor: from, toAnchor: to!, relation: .equal, constants: constants) let constraints = (view?.constraints ?? []) + (view?.superview?.constraints ?? []) diff --git a/Sources/iOS/Layout/LayoutConstraint.swift b/Sources/iOS/Layout/LayoutConstraint.swift index fe9a46710..18f5acd36 100644 --- a/Sources/iOS/Layout/LayoutConstraint.swift +++ b/Sources/iOS/Layout/LayoutConstraint.swift @@ -25,6 +25,9 @@ import UIKit +/// A typealias for NSLayoutConstraint.Relation +public typealias LayoutRelation = NSLayoutConstraint.Relation + internal struct LayoutConstraint { /// `From` anchor for the constraint. private let fromAnchor: LayoutAnchor @@ -33,17 +36,23 @@ internal struct LayoutConstraint { private let toAnchor: LayoutAnchor /// An array of constants for the constraint. - private var constants: [CGFloat] + private let constants: [CGFloat] + + /// A LayoutRelation between anchors. + private let relation: LayoutRelation + /** - An initializer taking `from` and `to` anchors and constants for the constraint. + An initializer taking `from` and `to` anchors, their `relation` and constants for the constraint. - Parameter fromAnchor: A LayoutAnchor. - Parameter toAnchor: A LayoutAnchor. + - Parameter relation: A LayoutRelation between anchors. - Parameter constants: An array of CGFloat. */ - init(fromAnchor: LayoutAnchor, toAnchor: LayoutAnchor, constants: [CGFloat]) { + init(fromAnchor: LayoutAnchor, toAnchor: LayoutAnchor, relation: LayoutRelation, constants: [CGFloat]) { self.fromAnchor = fromAnchor self.toAnchor = toAnchor + self.relation = relation self.constants = constants } } @@ -64,7 +73,7 @@ internal extension LayoutConstraint { zip(zip(fromAnchor.attributes, toAnchor.attributes), constants).forEach { v.append(NSLayoutConstraint(item: fromAnchor.constraintable as Any, attribute: $0.0, - relatedBy: .equal, + relatedBy: relation, toItem: toAnchor.constraintable, attribute: $0.1, multiplier: 1, From 7f3747914628fb4bde0d8139e05711fd0043ec89 Mon Sep 17 00:00:00 2001 From: Orkhan Alikhanov Date: Thu, 23 May 2019 00:24:26 +0400 Subject: [PATCH 2/3] Added relationer operators --- Sources/iOS/Layout/Layout.swift | 222 +++++++++++++++++++++----------- 1 file changed, 146 insertions(+), 76 deletions(-) diff --git a/Sources/iOS/Layout/Layout.swift b/Sources/iOS/Layout/Layout.swift index ee9c446a2..546a53985 100644 --- a/Sources/iOS/Layout/Layout.swift +++ b/Sources/iOS/Layout/Layout.swift @@ -198,61 +198,67 @@ public extension Layout { /** Constraints top of the view to its parent's. - Parameter _ offset: A CGFloat offset. + - Parameter _ relationer: A LayoutRelationer. - Returns: A Layout instance to allow chaining. */ @discardableResult - func top(_ offset: CGFloat = 0) -> Layout { - return constraint(.top, constant: offset) + func top(_ offset: CGFloat = 0, _ relationer: LayoutRelationer = LayoutRelationerStruct.equal) -> Layout { + return constraint(.top, relationer: relationer, constant: offset) } /** Constraints left of the view to its parent's. - Parameter _ offset: A CGFloat offset. + - Parameter _ relationer: A LayoutRelationer. - Returns: A Layout instance to allow chaining. */ @discardableResult - func left(_ offset: CGFloat = 0) -> Layout { - return constraint(.left, constant: offset) + func left(_ offset: CGFloat = 0, _ relationer: LayoutRelationer = LayoutRelationerStruct.equal) -> Layout { + return constraint(.left, relationer: relationer, constant: offset) } /** Constraints right of the view to its parent. - Parameter _ offset: A CGFloat offset. + - Parameter _ relationer: A LayoutRelationer. - Returns: A Layout instance to allow chaining. */ @discardableResult - func right(_ offset: CGFloat = 0) -> Layout { - return constraint(.right, constant: -offset) + func right(_ offset: CGFloat = 0, _ relationer: LayoutRelationer = LayoutRelationerStruct.equal) -> Layout { + return constraint(.right, relationer: relationer, constant: -offset) } /** Constraints leading of the view to its parent's. - Parameter _ offset: A CGFloat offset. + - Parameter _ relationer: A LayoutRelationer. - Returns: A Layout instance to allow chaining. */ @discardableResult - func leading(_ offset: CGFloat = 0) -> Layout { - return constraint(.leading, constant: offset) + func leading(_ offset: CGFloat = 0, _ relationer: LayoutRelationer = LayoutRelationerStruct.equal) -> Layout { + return constraint(.leading, relationer: relationer, constant: offset) } /** Constraints trailing of the view to its parent. - Parameter _ offset: A CGFloat offset. + - Parameter _ relationer: A LayoutRelationer. - Returns: A Layout instance to allow chaining. */ @discardableResult - func trailing(_ offset: CGFloat = 0) -> Layout { - return constraint(.trailing, constant: -offset) + func trailing(_ offset: CGFloat = 0, _ relationer: LayoutRelationer = LayoutRelationerStruct.equal) -> Layout { + return constraint(.trailing, relationer: relationer, constant: -offset) } /** Constraints bottom of the view to its parent's. - Parameter _ offset: A CGFloat offset. + - Parameter _ relationer: A LayoutRelationer. - Returns: A Layout instance to allow chaining. */ @discardableResult - func bottom(_ offset: CGFloat = 0) -> Layout { - return constraint(.bottom, constant: -offset) + func bottom(_ offset: CGFloat = 0, _ relationer: LayoutRelationer = LayoutRelationerStruct.equal) -> Layout { + return constraint(.bottom, relationer: relationer, constant: -offset) } /** @@ -390,41 +396,45 @@ public extension Layout { /** Constraints horizontal center of the view to its parent's. - Parameter _ offset: A CGFloat offset. + - Parameter _ relationer: A LayoutRelationer. - Returns: A Layout instance to allow chaining. */ @discardableResult - func centerX(_ offset: CGFloat = 0) -> Layout { - return constraint(.centerX, constant: offset) + func centerX(_ offset: CGFloat = 0, _ relationer: LayoutRelationer = LayoutRelationerStruct.equal) -> Layout { + return constraint(.centerX, relationer: relationer, constant: offset) } /** Constraints vertical center of the view to its parent's. - Parameter _ offset: A CGFloat offset. + - Parameter _ relationer: A LayoutRelationer. - Returns: A Layout instance to allow chaining. */ @discardableResult - func centerY(_ offset: CGFloat = 0) -> Layout { - return constraint(.centerY, constant: offset) + func centerY(_ offset: CGFloat = 0, _ relationer: LayoutRelationer = LayoutRelationerStruct.equal) -> Layout { + return constraint(.centerY, relationer: relationer, constant: offset) } /** Constraints width of the view to its parent's. - Parameter offset: A CGFloat offset. + - Parameter _ relationer: A LayoutRelationer. - Returns: A Layout instance to allow chaining. */ @discardableResult - func width(offset: CGFloat = 0) -> Layout { - return constraint(.width, constant: offset) + func width(offset: CGFloat = 0, _ relationer: LayoutRelationer = LayoutRelationerStruct.equal) -> Layout { + return constraint(.width, relationer: relationer, constant: offset) } /** Constraints height of the view to its parent's. - Parameter offset: A CGFloat offset. + - Parameter _ relationer: A LayoutRelationer. - Returns: A Layout instance to allow chaining. */ @discardableResult - func height(offset: CGFloat = 0) -> Layout { - return constraint(.height, constant: offset) + func height(offset: CGFloat = 0, _ relationer: LayoutRelationer = LayoutRelationerStruct.equal) -> Layout { + return constraint(.height, relationer: relationer, constant: offset) } /** @@ -445,61 +455,67 @@ public extension Layout { /** Constraints top of the view to its parent's safeArea. - Parameter _ offset: A CGFloat offset. + - Parameter _ relationer: A LayoutRelationer. - Returns: A Layout instance to allow chaining. */ @discardableResult - func topSafe(_ offset: CGFloat = 0) -> Layout { - return constraint(.top, constant: offset, useSafeArea: true) + func topSafe(_ offset: CGFloat = 0, _ relationer: LayoutRelationer = LayoutRelationerStruct.equal) -> Layout { + return constraint(.top, relationer: relationer, constant: offset, useSafeArea: true) } /** Constraints left of the view to its parent's safeArea. - Parameter _ offset: A CGFloat offset. + - Parameter _ relationer: A LayoutRelationer. - Returns: A Layout instance to allow chaining. */ @discardableResult - func leftSafe(_ offset: CGFloat = 0) -> Layout { - return constraint(.left, constant: offset, useSafeArea: true) + func leftSafe(_ offset: CGFloat = 0, _ relationer: LayoutRelationer = LayoutRelationerStruct.equal) -> Layout { + return constraint(.left, relationer: relationer, constant: offset, useSafeArea: true) } /** Constraints right of the view to its parent. - Parameter _ offset: A CGFloat offset. + - Parameter _ relationer: A LayoutRelationer. - Returns: A Layout instance to allow chaining. */ @discardableResult - func rightSafe(_ offset: CGFloat = 0) -> Layout { - return constraint(.right, constant: -offset, useSafeArea: true) + func rightSafe(_ offset: CGFloat = 0, _ relationer: LayoutRelationer = LayoutRelationerStruct.equal) -> Layout { + return constraint(.right, relationer: relationer, constant: -offset, useSafeArea: true) } /** Constraints leading of the view to its parent's safeArea. - Parameter _ offset: A CGFloat offset. + - Parameter _ relationer: A LayoutRelationer. - Returns: A Layout instance to allow chaining. */ @discardableResult - func leadingSafe(_ offset: CGFloat = 0) -> Layout { - return constraint(.leading, constant: offset, useSafeArea: true) + func leadingSafe(_ offset: CGFloat = 0, _ relationer: LayoutRelationer = LayoutRelationerStruct.equal) -> Layout { + return constraint(.leading, relationer: relationer, constant: offset, useSafeArea: true) } /** Constraints trailing of the view to its parent. - Parameter _ offset: A CGFloat offset. + - Parameter _ relationer: A LayoutRelationer. - Returns: A Layout instance to allow chaining. */ @discardableResult - func trailingSafe(_ offset: CGFloat = 0) -> Layout { - return constraint(.trailing, constant: -offset, useSafeArea: true) + func trailingSafe(_ offset: CGFloat = 0, _ relationer: LayoutRelationer = LayoutRelationerStruct.equal) -> Layout { + return constraint(.trailing, relationer: relationer, constant: -offset, useSafeArea: true) } /** Constraints bottom of the view to its parent's safeArea. - Parameter _ offset: A CGFloat offset. + - Parameter _ relationer: A LayoutRelationer. - Returns: A Layout instance to allow chaining. */ @discardableResult - func bottomSafe(_ offset: CGFloat = 0) -> Layout { - return constraint(.bottom, constant: -offset, useSafeArea: true) + func bottomSafe(_ offset: CGFloat = 0, _ relationer: LayoutRelationer = LayoutRelationerStruct.equal) -> Layout { + return constraint(.bottom, relationer: relationer, constant: -offset, useSafeArea: true) } /** @@ -637,41 +653,45 @@ public extension Layout { /** Constraints horizontal center of the view to its parent's safeArea. - Parameter _ offset: A CGFloat offset. + - Parameter _ relationer: A LayoutRelationer. - Returns: A Layout instance to allow chaining. */ @discardableResult - func centerXSafe(_ offset: CGFloat = 0) -> Layout { - return constraint(.centerX, constant: offset, useSafeArea: true) + func centerXSafe(_ offset: CGFloat = 0, _ relationer: LayoutRelationer = LayoutRelationerStruct.equal) -> Layout { + return constraint(.centerX, relationer: relationer, constant: offset, useSafeArea: true) } /** Constraints vertical center of the view to its parent's safeArea. - Parameter _ offset: A CGFloat offset. + - Parameter _ relationer: A LayoutRelationer. - Returns: A Layout instance to allow chaining. */ @discardableResult - func centerYSafe(_ offset: CGFloat = 0) -> Layout { - return constraint(.centerY, constant: offset, useSafeArea: true) + func centerYSafe(_ offset: CGFloat = 0, _ relationer: LayoutRelationer = LayoutRelationerStruct.equal) -> Layout { + return constraint(.centerY, relationer: relationer, constant: offset, useSafeArea: true) } /** Constraints width of the view to its parent's safeArea. - Parameter offset: A CGFloat offset. + - Parameter _ relationer: A LayoutRelationer. - Returns: A Layout instance to allow chaining. */ @discardableResult - func widthSafe(offset: CGFloat = 0) -> Layout { - return constraint(.width, constant: offset, useSafeArea: true) + func widthSafe(offset: CGFloat = 0, _ relationer: LayoutRelationer = LayoutRelationerStruct.equal) -> Layout { + return constraint(.width, relationer: relationer, constant: offset, useSafeArea: true) } /** Constraints height of the view to its parent's safeArea. - Parameter offset: A CGFloat offset. + - Parameter _ relationer: A LayoutRelationer. - Returns: A Layout instance to allow chaining. */ @discardableResult - func heightSafe(offset: CGFloat = 0) -> Layout { - return constraint(.height, constant: offset, useSafeArea: true) + func heightSafe(offset: CGFloat = 0, _ relationer: LayoutRelationer = LayoutRelationerStruct.equal) -> Layout { + return constraint(.height, relationer: relationer, constant: offset, useSafeArea: true) } /** @@ -692,21 +712,23 @@ public extension Layout { /** Constraints width of the view to a constant value. - Parameter _ width: A CGFloat value. + - Parameter _ relationer: A LayoutRelationer. - Returns: A Layout instance to allow chaining. */ @discardableResult - func width(_ width: CGFloat) -> Layout { - return constraint(.constantWidth, constants: width) + func width(_ width: CGFloat, _ relationer: LayoutRelationer = LayoutRelationerStruct.equal) -> Layout { + return constraint(.constantWidth, relationer: relationer, constants: width) } /** Constraints height of the view to a constant value. - Parameter _ height: A CGFloat value. + - Parameter _ relationer: A LayoutRelationer. - Returns: A Layout instance to allow chaining. */ @discardableResult - func height(_ height: CGFloat) -> Layout { - return constraint(.constantHeight, constants: height) + func height(_ height: CGFloat, _ relationer: LayoutRelationer = LayoutRelationerStruct.equal) -> Layout { + return constraint(.constantHeight, relationer: relationer, constants: height) } /** @@ -725,66 +747,72 @@ public extension Layout { Constraints top of the view to the given anchor. - Parameter _ anchor: A LayoutAnchorable. - Parameter _ offset: A CGFloat offset. + - Parameter _ relationer: A LayoutRelationer. - Returns: A Layout instance to allow chaining. */ @discardableResult - func top(_ anchor: LayoutAnchorable, _ offset: CGFloat = 0) -> Layout { - return constraint(.top, to: anchor, constant: offset) + func top(_ anchor: LayoutAnchorable, _ offset: CGFloat = 0, _ relationer: LayoutRelationer = LayoutRelationerStruct.equal) -> Layout { + return constraint(.top, to: anchor, relationer: relationer, constant: offset) } /** Constraints left of the view to the given anchor. - Parameter _ anchor: A LayoutAnchorable. - Parameter _ offset: A CGFloat offset. + - Parameter _ relationer: A LayoutRelationer. - Returns: A Layout instance to allow chaining. */ @discardableResult - func left(_ anchor: LayoutAnchorable, _ offset: CGFloat = 0) -> Layout { - return constraint(.left, to: anchor, constant: offset) + func left(_ anchor: LayoutAnchorable, _ offset: CGFloat = 0, _ relationer: LayoutRelationer = LayoutRelationerStruct.equal) -> Layout { + return constraint(.left, to: anchor, relationer: relationer, constant: offset) } /** Constraints right of the view to the given anchor. - Parameter _ anchor: A LayoutAnchorable. - Parameter _ offset: A CGFloat offset. + - Parameter _ relationer: A LayoutRelationer. - Returns: A Layout instance to allow chaining. */ @discardableResult - func right(_ anchor: LayoutAnchorable, _ offset: CGFloat = 0) -> Layout { - return constraint(.right, to: anchor, constant: -offset) + func right(_ anchor: LayoutAnchorable, _ offset: CGFloat = 0, _ relationer: LayoutRelationer = LayoutRelationerStruct.equal) -> Layout { + return constraint(.right, to: anchor, relationer: relationer, constant: -offset) } /** Constraints leading of the view to the given anchor. - Parameter _ anchor: A LayoutAnchorable. - Parameter _ offset: A CGFloat offset. + - Parameter _ relationer: A LayoutRelationer. - Returns: A Layout instance to allow chaining. */ @discardableResult - func leading(_ anchor: LayoutAnchorable, _ offset: CGFloat = 0) -> Layout { - return constraint(.leading, to: anchor, constant: offset) + func leading(_ anchor: LayoutAnchorable, _ offset: CGFloat = 0, _ relationer: LayoutRelationer = LayoutRelationerStruct.equal) -> Layout { + return constraint(.leading, to: anchor, relationer: relationer, constant: offset) } /** Constraints trailing of the view to the given anchor. - Parameter _ anchor: A LayoutAnchorable. - Parameter _ offset: A CGFloat offset. + - Parameter _ relationer: A LayoutRelationer. - Returns: A Layout instance to allow chaining. */ @discardableResult - func trailing(_ anchor: LayoutAnchorable, _ offset: CGFloat = 0) -> Layout { - return constraint(.trailing, to: anchor, constant: -offset) + func trailing(_ anchor: LayoutAnchorable, _ offset: CGFloat = 0, _ relationer: LayoutRelationer = LayoutRelationerStruct.equal) -> Layout { + return constraint(.trailing, to: anchor, relationer: relationer, constant: -offset) } /** Constraints bottom of the view to the given anchor. - Parameter _ anchor: A LayoutAnchorable. - Parameter _ offset: A CGFloat offset. + - Parameter _ relationer: A LayoutRelationer. - Returns: A Layout instance to allow chaining. */ @discardableResult - func bottom(_ anchor: LayoutAnchorable, _ offset: CGFloat = 0) -> Layout { - return constraint(.bottom, to: anchor, constant: -offset) + func bottom(_ anchor: LayoutAnchorable, _ offset: CGFloat = 0, _ relationer: LayoutRelationer = LayoutRelationerStruct.equal) -> Layout { + return constraint(.bottom, to: anchor, relationer: relationer, constant: -offset) } /** @@ -935,44 +963,48 @@ public extension Layout { Constraints horizontal center of the view to the given anchor. - Parameter _ anchor: A LayoutAnchorable. - Parameter _ offset: A CGFloat offset. + - Parameter _ relationer: A LayoutRelationer. - Returns: A Layout instance to allow chaining. */ @discardableResult - func centerX(_ anchor: LayoutAnchorable, _ offset: CGFloat = 0) -> Layout { - return constraint(.centerX, to: anchor, constant: offset) + func centerX(_ anchor: LayoutAnchorable, _ offset: CGFloat = 0, _ relationer: LayoutRelationer = LayoutRelationerStruct.equal) -> Layout { + return constraint(.centerX, to: anchor, relationer: relationer, constant: offset) } /** Constraints vertical center of the view to the given anchor. - Parameter _ anchor: A LayoutAnchorable. - Parameter _ offset: A CGFloat offset. + - Parameter _ relationer: A LayoutRelationer. - Returns: A Layout instance to allow chaining. */ @discardableResult - func centerY(_ anchor: LayoutAnchorable, _ offset: CGFloat = 0) -> Layout { - return constraint(.centerY, to: anchor, constant: offset) + func centerY(_ anchor: LayoutAnchorable, _ offset: CGFloat = 0, _ relationer: LayoutRelationer = LayoutRelationerStruct.equal) -> Layout { + return constraint(.centerY, to: anchor, relationer: relationer, constant: offset) } /** Constraints width of the view to the given anchor. - Parameter _ anchor: A LayoutAnchorable. - - Parameter offset: A CGFloat offset. + - Parameter _ offset: A CGFloat offset. + - Parameter _ relationer: A LayoutRelationer. - Returns: A Layout instance to allow chaining. */ @discardableResult - func width(_ anchor: LayoutAnchorable, _ offset: CGFloat = 0) -> Layout { - return constraint(.width, to: anchor, constant: offset) + func width(_ anchor: LayoutAnchorable, _ offset: CGFloat = 0, _ relationer: LayoutRelationer = LayoutRelationerStruct.equal) -> Layout { + return constraint(.width, to: anchor, relationer: relationer, constant: offset) } /** Constraints height of the view to the given anchor. - Parameter _ anchor: A LayoutAnchorable. - - Parameter offset: A CGFloat offset. + - Parameter _ offset: A CGFloat offset. + - Parameter _ relationer: A LayoutRelationer. - Returns: A Layout instance to allow chaining. */ @discardableResult - func height(_ anchor: LayoutAnchorable, _ offset: CGFloat = 0) -> Layout { - return constraint(.height, to: anchor, constant: offset) + func height(_ anchor: LayoutAnchorable, _ offset: CGFloat = 0, _ relationer: LayoutRelationer = LayoutRelationerStruct.equal) -> Layout { + return constraint(.height, to: anchor, relationer: relationer, constant: offset) } /** @@ -1051,21 +1083,23 @@ private extension Layout { Constraints the view to its parent according to the provided attribute. If the constraint already exists, will update its constant. - Parameter _ attribute: A LayoutAttribute. + - Parameter _ relationer: A LayoutRelationer. - Parameter constant: A CGFloat. - Returns: A Layout instance to allow chaining. */ - func constraint(_ attribute: LayoutAttribute, constant: CGFloat, useSafeArea: Bool = false) -> Layout { - return constraint([attribute], constants: constant, useSafeArea: useSafeArea) + func constraint(_ attribute: LayoutAttribute, relationer: LayoutRelationer = LayoutRelationerStruct.equal, constant: CGFloat, useSafeArea: Bool = false) -> Layout { + return constraint([attribute], relationer: relationer, constants: constant, useSafeArea: useSafeArea) } /** Constraints the view to its parent according to the provided attributes. If any of the constraints already exists, will update its constant. - Parameter _ attributes: An array of LayoutAttribute. + - Parameter _ relationer: A LayoutRelationer. - Parameter constants: A list of CGFloat. - Returns: A Layout instance to allow chaining. */ - func constraint(_ attributes: [LayoutAttribute], constants: CGFloat..., useSafeArea: Bool = false) -> Layout { + func constraint(_ attributes: [LayoutAttribute], relationer: LayoutRelationer = LayoutRelationerStruct.equal, constants: CGFloat..., useSafeArea: Bool = false) -> Layout { var attributes = attributes var anchor: LayoutAnchor! @@ -1080,7 +1114,7 @@ private extension Layout { anchor = LayoutAnchor(constraintable: useSafeArea ? parent?.safeAnchor.constraintable : parent, attributes: attributes) } - return constraint(attributes, to: anchor, constants: constants) + return constraint(attributes, to: anchor, relationer: relationer, constants: constants) } /** @@ -1088,11 +1122,12 @@ private extension Layout { If the constraint already exists, will update its constant. - Parameter _ attribute: A LayoutAttribute. - Parameter to anchor: A LayoutAnchorable. + - Parameter relation: A LayoutRelation between anchors. - Parameter constant: A CGFloat. - Returns: A Layout instance to allow chaining. */ - func constraint(_ attribute: LayoutAttribute, to anchor: LayoutAnchorable, constant: CGFloat) -> Layout { - return constraint([attribute], to: anchor, constants: constant) + func constraint(_ attribute: LayoutAttribute, to anchor: LayoutAnchorable, relationer: LayoutRelationer = LayoutRelationerStruct.equal, constant: CGFloat) -> Layout { + return constraint([attribute], to: anchor, relationer: relationer, constants: constant) } /** @@ -1100,11 +1135,12 @@ private extension Layout { If any of the constraints already exists, will update its constant. - Parameter _ attributes: An array of LayoutAttribute. - Parameter to anchor: A LayoutAnchorable. + - Parameter relation: A LayoutRelation between anchors. - Parameter constants: A list of CGFloat. - Returns: A Layout instance to allow chaining. */ - func constraint(_ attributes: [LayoutAttribute], to anchor: LayoutAnchorable, constants: CGFloat...) -> Layout { - return constraint(attributes, to: anchor, constants: constants) + func constraint(_ attributes: [LayoutAttribute], to anchor: LayoutAnchorable, relationer: LayoutRelationer = LayoutRelationerStruct.equal, constants: CGFloat...) -> Layout { + return constraint(attributes, to: anchor, relationer: relationer, constants: constants) } /** @@ -1112,17 +1148,18 @@ private extension Layout { If any of the constraints already exists, will update its constant. - Parameter _ attributes: An array of LayoutAttribute. - Parameter to anchor: A LayoutAnchorable. + - Parameter relation: A LayoutRelation between anchors. - Parameter constants: An array of CGFloat. - Returns: A Layout instance to allow chaining. */ - func constraint(_ attributes: [LayoutAttribute], to anchor: LayoutAnchorable, constants: [CGFloat]) -> Layout { + func constraint(_ attributes: [LayoutAttribute], to anchor: LayoutAnchorable, relationer: LayoutRelationer, constants: [CGFloat]) -> Layout { let from = LayoutAnchor(constraintable: constraintable, attributes: attributes) var to = anchor as? LayoutAnchor if to?.attributes.isEmpty ?? true { let v = (anchor as? UIView) ?? (anchor as? LayoutAnchor)?.constraintable to = LayoutAnchor(constraintable: v, attributes: attributes) } - let constraint = LayoutConstraint(fromAnchor: from, toAnchor: to!, relation: .equal, constants: constants) + let constraint = LayoutConstraint(fromAnchor: from, toAnchor: to!, relation: relationer(.nil, .nil), constants: constants) let constraints = (view?.constraints ?? []) + (view?.superview?.constraints ?? []) @@ -1140,3 +1177,36 @@ private extension Layout { return self } } + +/// A closure typealias for relation operators. +public typealias LayoutRelationer = (LayoutRelationerStruct, LayoutRelationerStruct) -> LayoutRelation + +/// A dummy struct used in creating relation operators (==, >=, <=). +public struct LayoutRelationerStruct { + /// Passed as an unused argument to the LayoutRelationer closures. + static let `nil` = LayoutRelationerStruct() + + /** + A method used as a default parameter for LayoutRelationer closures. + Swift does not allow using == operator directly, so we had to create this. + */ + public static func equal(left: LayoutRelationerStruct, right: LayoutRelationerStruct) -> LayoutRelation { + return .equal + } +} + +/// A method returning `LayoutRelation.equal` +public func ==(left: LayoutRelationerStruct, right: LayoutRelationerStruct) -> LayoutRelation { + return .equal +} + +/// A method returning `LayoutRelation.greaterThanOrEqual` +public func >=(left: LayoutRelationerStruct, right: LayoutRelationerStruct) -> LayoutRelation { + return .greaterThanOrEqual +} + +/// A method returning `LayoutRelation.lessThanOrEqual` +public func <=(left: LayoutRelationerStruct, right: LayoutRelationerStruct) -> LayoutRelation { + return .lessThanOrEqual +} + From de7e9624445121b5ae5a6db68400c33bc80728ad Mon Sep 17 00:00:00 2001 From: Daniel Dahan Date: Fri, 24 May 2019 12:34:51 -0400 Subject: [PATCH 3/3] added layout constraints and added installation instructions to README --- CHANGELOG.md | 7 +++++++ Material.podspec | 2 +- README.md | 42 ++++++++++++++++++++++++++++++++++++++- Sources/Frameworks/Motion | 2 +- Sources/Info.plist | 2 +- 5 files changed, 51 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 29a264611..932e67342 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## 3.1.3 + +* Added installation instructions to README. + +- [pr-1236](https://github.com/CosmicMind/Material/pull/1236): Added Layout relations. + - [issue-1220](https://github.com/CosmicMind/Material/issues/1220): Support all relations for Layout constraints. + ## 3.1.2 - [pr-1233](https://github.com/CosmicMind/Material/pull/1233): Fixed Layout breaks - subview ordering. diff --git a/Material.podspec b/Material.podspec index d86ea584c..518d02048 100755 --- a/Material.podspec +++ b/Material.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'Material' - s.version = '3.1.2' + s.version = '3.1.3' s.swift_version = '5.0' s.license = 'BSD-3-Clause' s.summary = 'A UI/UX framework for creating beautiful applications.' diff --git a/README.md b/README.md index 8af9114ef..06d864c9d 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,47 @@ Take a look at [Sample Projects](https://github.com/CosmicMind/Samples) to get y > **Embedded frameworks require a minimum deployment target of iOS 8+.** > - [Download Material](https://github.com/CosmicMind/Material/archive/master.zip) -Read [Material - It's time to download](https://www.cosmicmind.com/danieldahan/lesson/6) to learn how to install Material & Motion using [GitHub](http://github.com), [CocoaPods](http://cocoapods.org), and [Carthage](https://github.com/Carthage/Carthage). +## CocoaPods + +[CocoaPods](http://cocoapods.org) is a dependency manager for Cocoa projects. You can install it with the following command: + +```bash +$ gem install cocoapods +``` + +To integrate Material's core features into your Xcode project using CocoaPods, specify it in your `Podfile`: + +```ruby +source 'https://github.com/CocoaPods/Specs.git' +platform :ios, '8.0' +use_frameworks! + +pod 'Material', '~> 3.1.0' +``` + +Then, run the following command: + +```bash +$ pod install +``` + +## Carthage + +Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks. + +You can install Carthage with Homebrew using the following command: + +```bash +$ brew update +$ brew install carthage +``` +To integrate Material into your Xcode project using Carthage, specify it in your Cartfile: + +```bash +github "CosmicMind/Material" +``` + +Run `carthage update` to build the framework and drag the built `Material.framework` into your Xcode project. ## Change Log diff --git a/Sources/Frameworks/Motion b/Sources/Frameworks/Motion index a5927ef45..cb489ea37 160000 --- a/Sources/Frameworks/Motion +++ b/Sources/Frameworks/Motion @@ -1 +1 @@ -Subproject commit a5927ef45c99f57edcb18b48a80555659598046a +Subproject commit cb489ea37adff56f805755b285e2e1721adaf9ea diff --git a/Sources/Info.plist b/Sources/Info.plist index 7ab04bf1f..b0eb15353 100644 --- a/Sources/Info.plist +++ b/Sources/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 3.1.2 + 3.1.3 CFBundleSignature ???? CFBundleVersion