From 42f39154df90aceffa8c8e86e4e20c2b7d16ba34 Mon Sep 17 00:00:00 2001 From: S4cha Date: Wed, 1 Apr 2020 10:33:15 +0200 Subject: [PATCH 01/12] Adds "Subviews" function builder + tests --- Sources/Stevia/Stevia+Hierarchy.swift | 84 ++++++++++++++++++++++++++ Tests/SteviaTests/HierarchyTests.swift | 61 ++++++++++--------- 2 files changed, 117 insertions(+), 28 deletions(-) diff --git a/Sources/Stevia/Stevia+Hierarchy.swift b/Sources/Stevia/Stevia+Hierarchy.swift index 3b6087d8..4df7f77b 100644 --- a/Sources/Stevia/Stevia+Hierarchy.swift +++ b/Sources/Stevia/Stevia+Hierarchy.swift @@ -9,6 +9,12 @@ #if canImport(UIKit) import UIKit +@_functionBuilder public struct SubviewsBuilder { + public static func buildBlock(_ content: UIView...) -> [UIView] { + return content + } +} + public extension UIView { /** @@ -47,6 +53,84 @@ public extension UIView { func sv(_ subViews: UIView...) -> UIView { return sv(subViews) } + + /** + Defines the view hierachy for the view. + + Esentially, this is just a shortcut to `addSubview` + and 'translatesAutoresizingMaskIntoConstraints = false' + + + + ``` + class MyView: UIView { + + let email = UITextField() + let password = UITextField() + let login = UIButton() + + convenience init() { + self.init(frame: CGRect.zero) + + Subviews { + email + password + login + } + ... + + } + } + + ``` + + - Returns: Itself to enable nested layouts. + */ + @discardableResult + func Subviews(@SubviewsBuilder content: () -> [UIView]) -> UIView { + let subviews = content() + sv(subviews) + return self + } + + /** + Defines the view hierachy for the view. + + Esentially, this is just a shortcut to `addSubview` + and 'translatesAutoresizingMaskIntoConstraints = false' + + + + ``` + class MyView: UIView { + + let email = UITextField() + let password = UITextField() + let login = UIButton() + + convenience init() { + self.init(frame: CGRect.zero) + + Subviews { + email + password + login + } + ... + + } + } + + ``` + + - Returns: Itself to enable nested layouts. + */ + @discardableResult + func Subviews(@SubviewsBuilder content: () -> UIView) -> UIView { + let subview = content() + sv(subview) + return self + } /** Defines the view hierachy for the view. diff --git a/Tests/SteviaTests/HierarchyTests.swift b/Tests/SteviaTests/HierarchyTests.swift index e4b38f1a..1edd00ad 100644 --- a/Tests/SteviaTests/HierarchyTests.swift +++ b/Tests/SteviaTests/HierarchyTests.swift @@ -34,21 +34,6 @@ class HierarchyTests: XCTestCase { XCTAssertFalse(v2.translatesAutoresizingMaskIntoConstraints) } - func testVariadicSv() { - let view = UIView() - let v1 = UIView() - let v2 = UIView() - view.sv( - v1, - v2 - ) - XCTAssertEqual(view.subviews.count, 2) - XCTAssertTrue(view.subviews.contains(v1)) - XCTAssertTrue(view.subviews.contains(v2)) - XCTAssertFalse(v1.translatesAutoresizingMaskIntoConstraints) - XCTAssertFalse(v2.translatesAutoresizingMaskIntoConstraints) - } - func testTableViewCellSV() { let cell = UITableViewCell() let v1 = UIView() @@ -56,16 +41,16 @@ class HierarchyTests: XCTestCase { cell.sv( v1, v2 - ) + ) XCTAssertEqual(cell.contentView.subviews.count, 2) XCTAssertTrue(cell.contentView.subviews.contains(v1)) XCTAssertTrue(cell.contentView.subviews.contains(v2)) XCTAssertFalse(v1.translatesAutoresizingMaskIntoConstraints) XCTAssertFalse(v2.translatesAutoresizingMaskIntoConstraints) } - - func testTableViewCellVariadicSV() { - let cell = UITableViewCell() + + func testCollectionViewCellSV() { + let cell = UICollectionViewCell() let v1 = UIView() let v2 = UIView() cell.sv( @@ -78,15 +63,35 @@ class HierarchyTests: XCTestCase { XCTAssertFalse(v1.translatesAutoresizingMaskIntoConstraints) XCTAssertFalse(v2.translatesAutoresizingMaskIntoConstraints) } + + // Function Builders version + + func testSubviews() { + let view = UIView() + let v1 = UIView() + let v2 = UIView() + view.Subviews { + v1 + v2 + } + XCTAssertEqual(view.subviews.count, 2) + XCTAssertTrue(view.subviews.contains(v1)) + XCTAssertTrue(view.subviews.contains(v2)) + XCTAssertFalse(v1.translatesAutoresizingMaskIntoConstraints) + XCTAssertFalse(v2.translatesAutoresizingMaskIntoConstraints) + } - func testCollectionViewCellSV() { - let cell = UICollectionViewCell() + + func testTableViewCellSubviews() { + let cell = UITableViewCell() let v1 = UIView() let v2 = UIView() - cell.sv( - v1, + cell.Subviews { + v1 v2 - ) + } + + XCTAssertEqual(cell.contentView.subviews.count, 2) XCTAssertTrue(cell.contentView.subviews.contains(v1)) XCTAssertTrue(cell.contentView.subviews.contains(v2)) @@ -94,14 +99,14 @@ class HierarchyTests: XCTestCase { XCTAssertFalse(v2.translatesAutoresizingMaskIntoConstraints) } - func testCollectionViewCellVariadicSV() { + func testCollectionViewCellSubviews() { let cell = UICollectionViewCell() let v1 = UIView() let v2 = UIView() - cell.sv( - v1, + cell.Subviews { + v1 v2 - ) + } XCTAssertEqual(cell.contentView.subviews.count, 2) XCTAssertTrue(cell.contentView.subviews.contains(v1)) XCTAssertTrue(cell.contentView.subviews.contains(v2)) From f609ca26a355af8156d3e12f844c7245f3cb9129 Mon Sep 17 00:00:00 2001 From: S4cha Date: Wed, 1 Apr 2020 16:04:26 +0200 Subject: [PATCH 02/12] Updates Api with function builder + replaces CGFloat by Double --- .../LoginStevia/LoginViewStevia.swift | 26 ++-- Sources/Stevia/Stevia+Alignment.swift | 6 +- Sources/Stevia/Stevia+Center.swift | 4 +- Sources/Stevia/Stevia+Constraints.swift | 10 +- Sources/Stevia/Stevia+DoubleDash.swift | 4 +- Sources/Stevia/Stevia+Equation.swift | 28 ++--- Sources/Stevia/Stevia+Fill.swift | 12 +- Sources/Stevia/Stevia+FlexibleMargin.swift | 21 +++- Sources/Stevia/Stevia+Hierarchy.swift | 1 + Sources/Stevia/Stevia+LayoutAnchors.swift | 32 ++--- Sources/Stevia/Stevia+Operators.swift | 73 ++++++++--- Sources/Stevia/Stevia+Percentage.swift | 12 +- Sources/Stevia/Stevia+Position.swift | 14 +-- Sources/Stevia/Stevia+Size.swift | 74 ++++++++++- Sources/Stevia/Stevia+Stacks.swift | 67 ++++++++-- Tests/SteviaTests/BaselineTests.swift | 13 +- Tests/SteviaTests/CenterTests.swift | 2 +- Tests/SteviaTests/EquationTests.swift | 116 +++++++++--------- Tests/SteviaTests/FillTests.swift | 11 +- Tests/SteviaTests/FlexibleMarginTests.swift | 19 ++- Tests/SteviaTests/FullLayoutTests.swift | 45 +++---- Tests/SteviaTests/GetConstraintsTests.swift | 2 +- Tests/SteviaTests/HierarchyTests.swift | 33 ++++- Tests/SteviaTests/LayoutTests.swift | 68 +++++++--- Tests/SteviaTests/PositionTests.swift | 2 +- Tests/SteviaTests/SizeTests.swift | 51 +++++--- 26 files changed, 500 insertions(+), 246 deletions(-) diff --git a/LoginExample/LoginStevia/LoginViewStevia.swift b/LoginExample/LoginStevia/LoginViewStevia.swift index 0a5c1b87..70aaef23 100644 --- a/LoginExample/LoginStevia/LoginViewStevia.swift +++ b/LoginExample/LoginStevia/LoginViewStevia.swift @@ -22,24 +22,24 @@ class LoginViewStevia: UIView { // View Hierarchy // This essentially does `translatesAutoresizingMaskIntoConstraints = false` // and `addSubsview()`. The neat benefit is that - // (`sv` calls can be nested which will visually show hierarchy ! ) - sv( - email, - password, + // (`Subviews` calls can be nested which will visually show hierarchy ! ) + Subviews { + email + password login - ) + } // Vertical + Horizontal Layout in one pass // With type-safe visual format - layout( - 100, - |-email-| ~ 80, - 8, - |-password-| ~ 80, - "", - |login| ~ 80, + Layout { + 100 + |-email-| ~ 80 + 8 + |-password-| ~ 80 + >=20 + |login| ~ 80 0 - ) + } // ⛓ Chainable api // email.top(100).fillHorizontally(m: 8).height(80) diff --git a/Sources/Stevia/Stevia+Alignment.swift b/Sources/Stevia/Stevia+Alignment.swift index 99062d6d..fe6b4d74 100644 --- a/Sources/Stevia/Stevia+Alignment.swift +++ b/Sources/Stevia/Stevia+Alignment.swift @@ -121,7 +121,7 @@ public func alignCenter(_ v1: UIView, with v2: UIView) { ``` */ -public func alignHorizontally(_ v1: UIView, with v2: UIView, offset: CGFloat = 0) { +public func alignHorizontally(_ v1: UIView, with v2: UIView, offset: Double = 0) { align(.horizontal, v1: v1, with: v2, offset: offset) } @@ -133,7 +133,7 @@ public func alignHorizontally(_ v1: UIView, with v2: UIView, offset: CGFloat = 0 ``` */ -public func alignVertically(_ v1: UIView, with v2: UIView, offset: CGFloat = 0) { +public func alignVertically(_ v1: UIView, with v2: UIView, offset: Double = 0) { align(.vertical, v1: v1, with: v2, offset: offset) } @@ -148,7 +148,7 @@ private func align(_ axis: NSLayoutConstraint.Axis, views: [UIView]) { } } -private func align(_ axis: NSLayoutConstraint.Axis, v1: UIView, with v2: UIView, offset: CGFloat) { +private func align(_ axis: NSLayoutConstraint.Axis, v1: UIView, with v2: UIView, offset: Double) { if let spv = v1.superview { let center: NSLayoutConstraint.Attribute = axis == .horizontal ? .centerY : .centerX let c = constraint(item: v1, attribute: center, toItem: v2, constant: offset) diff --git a/Sources/Stevia/Stevia+Center.swift b/Sources/Stevia/Stevia+Center.swift index d5b4df33..cb03bf93 100644 --- a/Sources/Stevia/Stevia+Center.swift +++ b/Sources/Stevia/Stevia+Center.swift @@ -76,7 +76,7 @@ public extension UIView { */ @discardableResult - func centerHorizontally(_ offset: CGFloat) -> Self { + func centerHorizontally(_ offset: Double) -> Self { if let spv = superview { alignVertically(self, with: spv, offset: offset) } @@ -94,7 +94,7 @@ public extension UIView { */ @discardableResult - func centerVertically(_ offset: CGFloat) -> Self { + func centerVertically(_ offset: Double) -> Self { if let spv = superview { alignHorizontally(self, with: spv, offset: offset) } diff --git a/Sources/Stevia/Stevia+Constraints.swift b/Sources/Stevia/Stevia+Constraints.swift index 5d740eef..f13202e6 100644 --- a/Sources/Stevia/Stevia+Constraints.swift +++ b/Sources/Stevia/Stevia+Constraints.swift @@ -41,8 +41,8 @@ public extension UIView { relatedBy: NSLayoutConstraint.Relation = .equal, toItem view2: AnyObject? = nil, attribute attr2: NSLayoutConstraint.Attribute? = nil, - multiplier: CGFloat = 1, - constant: CGFloat = 0) -> NSLayoutConstraint { + multiplier: Double = 1, + constant: Double = 0) -> NSLayoutConstraint { let c = constraint( item: view1, attribute: attr1, relatedBy: relatedBy, @@ -74,12 +74,12 @@ func constraint(item view1: AnyObject, relatedBy: NSLayoutConstraint.Relation = .equal, toItem view2: AnyObject? = nil, attribute attr2: NSLayoutConstraint.Attribute? = nil, // Not an attribute?? - multiplier: CGFloat = 1, - constant: CGFloat = 0) -> NSLayoutConstraint { + multiplier: Double = 1, + constant: Double = 0) -> NSLayoutConstraint { let c = NSLayoutConstraint(item: view1, attribute: attr1, relatedBy: relatedBy, toItem: view2, attribute: ((attr2 == nil) ? attr1 : attr2! ), - multiplier: multiplier, constant: constant) + multiplier: CGFloat(multiplier), constant: CGFloat(constant)) c.priority = UILayoutPriority(rawValue: UILayoutPriority.defaultHigh.rawValue + 1) return c } diff --git a/Sources/Stevia/Stevia+DoubleDash.swift b/Sources/Stevia/Stevia+DoubleDash.swift index 7a7ea3a4..db87d5da 100644 --- a/Sources/Stevia/Stevia+DoubleDash.swift +++ b/Sources/Stevia/Stevia+DoubleDash.swift @@ -12,7 +12,7 @@ import UIKit infix operator -- :AdditionPrecedence @discardableResult -public func -- (left: UIView, right: CGFloat) -> PartialConstraint { +public func -- (left: UIView, right: Double) -> PartialConstraint { return left-right } @@ -42,7 +42,7 @@ public func -- (left: UIView, right: UIView) -> [UIView] { } @discardableResult -public func -- (left: [UIView], right: CGFloat) -> PartialConstraint { +public func -- (left: [UIView], right: Double) -> PartialConstraint { return left-right } diff --git a/Sources/Stevia/Stevia+Equation.swift b/Sources/Stevia/Stevia+Equation.swift index 9fd79b16..cc45fb34 100644 --- a/Sources/Stevia/Stevia+Equation.swift +++ b/Sources/Stevia/Stevia+Equation.swift @@ -12,8 +12,8 @@ import UIKit public struct SteviaAttribute { let view: UIView let attribute: NSLayoutConstraint.Attribute - let constant: CGFloat? - let multiplier: CGFloat? + let constant: Double? + let multiplier: Double? init(view: UIView, attribute: NSLayoutConstraint.Attribute) { self.view = view @@ -22,7 +22,7 @@ public struct SteviaAttribute { self.multiplier = nil } - init(view: UIView, attribute: NSLayoutConstraint.Attribute, constant: CGFloat?, multiplier: CGFloat?) { + init(view: UIView, attribute: NSLayoutConstraint.Attribute, constant: Double?, multiplier: Double?) { self.view = view self.attribute = attribute self.constant = constant @@ -183,37 +183,37 @@ private func applyRelation(left: SteviaAttribute, right: SteviaAttribute, relate } @discardableResult -public func + (left: SteviaAttribute, right: CGFloat) -> SteviaAttribute { +public func + (left: SteviaAttribute, right: Double) -> SteviaAttribute { return SteviaAttribute(view: left.view, attribute: left.attribute, constant: right, multiplier: left.multiplier) } @discardableResult -public func - (left: SteviaAttribute, right: CGFloat) -> SteviaAttribute { +public func - (left: SteviaAttribute, right: Double) -> SteviaAttribute { return SteviaAttribute(view: left.view, attribute: left.attribute, constant: -right, multiplier: left.multiplier) } @discardableResult -public func * (left: SteviaAttribute, right: CGFloat) -> SteviaAttribute { +public func * (left: SteviaAttribute, right: Double) -> SteviaAttribute { return SteviaAttribute(view: left.view, attribute: left.attribute, constant: left.constant, multiplier: right) } @discardableResult -public func / (left: SteviaAttribute, right: CGFloat) -> SteviaAttribute { +public func / (left: SteviaAttribute, right: Double) -> SteviaAttribute { return left * (1/right) } @discardableResult -public func % (left: CGFloat, right: SteviaAttribute) -> SteviaAttribute { +public func % (left: Double, right: SteviaAttribute) -> SteviaAttribute { return right * (left/100) } // MARK: - Equations of type v.P == X @discardableResult -public func == (left: SteviaAttribute, right: CGFloat) -> NSLayoutConstraint { +public func == (left: SteviaAttribute, right: Double) -> NSLayoutConstraint { if let spv = left.view.superview { var toItem: UIView? = spv - var constant: CGFloat = right + var constant = right if left.attribute == .width || left.attribute == .height { toItem = nil } @@ -229,10 +229,10 @@ public func == (left: SteviaAttribute, right: CGFloat) -> NSLayoutConstraint { } @discardableResult -public func >= (left: SteviaAttribute, right: CGFloat) -> NSLayoutConstraint { +public func >= (left: SteviaAttribute, right: Double) -> NSLayoutConstraint { if let spv = left.view.superview { var toItem: UIView? = spv - var constant: CGFloat = right + var constant = right if left.attribute == .width || left.attribute == .height { toItem = nil } @@ -249,10 +249,10 @@ public func >= (left: SteviaAttribute, right: CGFloat) -> NSLayoutConstraint { } @discardableResult -public func <= (left: SteviaAttribute, right: CGFloat) -> NSLayoutConstraint { +public func <= (left: SteviaAttribute, right: Double) -> NSLayoutConstraint { if let spv = left.view.superview { var toItem: UIView? = spv - var constant: CGFloat = right + var constant = right if left.attribute == .width || left.attribute == .height { toItem = nil } diff --git a/Sources/Stevia/Stevia+Fill.swift b/Sources/Stevia/Stevia+Fill.swift index 4082664d..e54b9a27 100644 --- a/Sources/Stevia/Stevia+Fill.swift +++ b/Sources/Stevia/Stevia+Fill.swift @@ -16,7 +16,7 @@ public extension UIView { A padding can be used to apply equal spaces between the view and its superview */ @discardableResult - func fillContainer(_ padding: CGFloat = 0) -> Self { + func fillContainer(_ padding: Double = 0) -> Self { fillHorizontally(m: padding) fillVertically(m: padding) return self @@ -27,7 +27,7 @@ public extension UIView { Adds the constraints needed for the view to fill its `superview` Vertically. A padding can be used to apply equal spaces between the view and its superview */ - func fillV(m points: CGFloat = 0) -> Self { + func fillV(m points: Double = 0) -> Self { return fill(.vertical, points: points) } @@ -36,7 +36,7 @@ public extension UIView { A padding can be used to apply equal spaces between the view and its superview */ @discardableResult - func fillVertically(m points: CGFloat = 0) -> Self { + func fillVertically(m points: Double = 0) -> Self { return fill(.vertical, points: points) } @@ -45,7 +45,7 @@ public extension UIView { Adds the constraints needed for the view to fill its `superview` Horizontally. A padding can be used to apply equal spaces between the view and its superview */ - func fillH(m points: CGFloat = 0) -> Self { + func fillH(m points: Double = 0) -> Self { return fill(.horizontal, points: points) } @@ -54,11 +54,11 @@ public extension UIView { A padding can be used to apply equal spaces between the view and its superview */ @discardableResult - func fillHorizontally(m points: CGFloat = 0) -> Self { + func fillHorizontally(m points: Double = 0) -> Self { return fill(.horizontal, points: points) } - fileprivate func fill(_ axis: NSLayoutConstraint.Axis, points: CGFloat = 0) -> Self { + fileprivate func fill(_ axis: NSLayoutConstraint.Axis, points: Double = 0) -> Self { let a: NSLayoutConstraint.Attribute = axis == .vertical ? .top : .leading let b: NSLayoutConstraint.Attribute = axis == .vertical ? .bottom : .trailing if let spv = superview { diff --git a/Sources/Stevia/Stevia+FlexibleMargin.swift b/Sources/Stevia/Stevia+FlexibleMargin.swift index d260e073..d3f23c65 100644 --- a/Sources/Stevia/Stevia+FlexibleMargin.swift +++ b/Sources/Stevia/Stevia+FlexibleMargin.swift @@ -11,18 +11,29 @@ import UIKit prefix operator >= @discardableResult -public prefix func >= (p: CGFloat) -> SteviaFlexibleMargin { - return SteviaFlexibleMargin(points: p, relation: .greaterThanOrEqual) +public prefix func >= (p: Double) -> SteviaFlexibleMargin { + SteviaFlexibleMargin(points: p, relation: .greaterThanOrEqual) } +@discardableResult +public prefix func >= (p: Int) -> SteviaFlexibleMargin { + SteviaFlexibleMargin(points: Double(p), relation: .greaterThanOrEqual) +} + + prefix operator <= @discardableResult -public prefix func <= (p: CGFloat) -> SteviaFlexibleMargin { - return SteviaFlexibleMargin(points: p, relation: .lessThanOrEqual) +public prefix func <= (p: Double) -> SteviaFlexibleMargin { + SteviaFlexibleMargin(points: p, relation: .lessThanOrEqual) +} + +@discardableResult +public prefix func <= (p: Int) -> SteviaFlexibleMargin { + SteviaFlexibleMargin(points: Double(p), relation: .lessThanOrEqual) } public struct SteviaFlexibleMargin { - var points: CGFloat! + var points: Double! var relation: NSLayoutConstraint.Relation! } diff --git a/Sources/Stevia/Stevia+Hierarchy.swift b/Sources/Stevia/Stevia+Hierarchy.swift index 4df7f77b..d3067eaf 100644 --- a/Sources/Stevia/Stevia+Hierarchy.swift +++ b/Sources/Stevia/Stevia+Hierarchy.swift @@ -49,6 +49,7 @@ public extension UIView { - Returns: Itself to enable nested layouts. */ + @available(*, deprecated, message: "Use Subviews { } function builder instead.") @discardableResult func sv(_ subViews: UIView...) -> UIView { return sv(subViews) diff --git a/Sources/Stevia/Stevia+LayoutAnchors.swift b/Sources/Stevia/Stevia+LayoutAnchors.swift index 902cb410..8bd0aa03 100644 --- a/Sources/Stevia/Stevia+LayoutAnchors.swift +++ b/Sources/Stevia/Stevia+LayoutAnchors.swift @@ -12,9 +12,9 @@ import UIKit @available(iOS 9.0, *) public struct SteviaLayoutYAxisAnchor { let anchor: NSLayoutYAxisAnchor - let constant: CGFloat + let constant: Double - init(anchor: NSLayoutYAxisAnchor, constant: CGFloat = 0) { + init(anchor: NSLayoutYAxisAnchor, constant: Double = 0) { self.anchor = anchor self.constant = constant } @@ -23,9 +23,9 @@ public struct SteviaLayoutYAxisAnchor { @available(iOS 9.0, *) public struct SteviaLayoutXAxisAnchor { let anchor: NSLayoutXAxisAnchor - let constant: CGFloat + let constant: Double - init(anchor: NSLayoutXAxisAnchor, constant: CGFloat = 0) { + init(anchor: NSLayoutXAxisAnchor, constant: Double = 0) { self.anchor = anchor self.constant = constant } @@ -74,15 +74,15 @@ public func == (left: SteviaAttribute, right: SteviaLayoutYAxisAnchor) -> NSLayo var constraint = NSLayoutConstraint() if left.attribute == .top { - constraint = left.view.topAnchor.constraint(equalTo: right.anchor, constant: right.constant) + constraint = left.view.topAnchor.constraint(equalTo: right.anchor, constant: CGFloat(right.constant)) } if left.attribute == .bottom { - constraint = left.view.bottomAnchor.constraint(equalTo: right.anchor, constant: right.constant) + constraint = left.view.bottomAnchor.constraint(equalTo: right.anchor, constant: CGFloat(right.constant)) } if left.attribute == .centerY { - constraint = left.view.centerYAnchor.constraint(equalTo: right.anchor, constant: right.constant) + constraint = left.view.centerYAnchor.constraint(equalTo: right.anchor, constant: CGFloat(right.constant)) } constraint.isActive = true @@ -96,23 +96,23 @@ public func == (left: SteviaAttribute, right: SteviaLayoutXAxisAnchor) -> NSLayo var constraint = NSLayoutConstraint() if left.attribute == .left { - constraint = left.view.leftAnchor.constraint(equalTo: right.anchor, constant: right.constant) + constraint = left.view.leftAnchor.constraint(equalTo: right.anchor, constant: CGFloat(right.constant)) } if left.attribute == .right { - constraint = left.view.rightAnchor.constraint(equalTo: right.anchor, constant: right.constant) + constraint = left.view.rightAnchor.constraint(equalTo: right.anchor, constant: CGFloat(right.constant)) } if left.attribute == .leading { - constraint = left.view.leadingAnchor.constraint(equalTo: right.anchor, constant: right.constant) + constraint = left.view.leadingAnchor.constraint(equalTo: right.anchor, constant: CGFloat(right.constant)) } if left.attribute == .trailing { - constraint = left.view.trailingAnchor.constraint(equalTo: right.anchor, constant: right.constant) + constraint = left.view.trailingAnchor.constraint(equalTo: right.anchor, constant: CGFloat(right.constant)) } if left.attribute == .centerX { - constraint = left.view.centerXAnchor.constraint(equalTo: right.anchor, constant: right.constant) + constraint = left.view.centerXAnchor.constraint(equalTo: right.anchor, constant: CGFloat(right.constant)) } constraint.isActive = true @@ -123,25 +123,25 @@ public func == (left: SteviaAttribute, right: SteviaLayoutXAxisAnchor) -> NSLayo @available(iOS 9.0, *) @discardableResult -public func + (left: SteviaLayoutYAxisAnchor, right: CGFloat) -> SteviaLayoutYAxisAnchor { +public func + (left: SteviaLayoutYAxisAnchor, right: Double) -> SteviaLayoutYAxisAnchor { return SteviaLayoutYAxisAnchor(anchor: left.anchor, constant: right) } @available(iOS 9.0, *) @discardableResult -public func - (left: SteviaLayoutYAxisAnchor, right: CGFloat) -> SteviaLayoutYAxisAnchor { +public func - (left: SteviaLayoutYAxisAnchor, right: Double) -> SteviaLayoutYAxisAnchor { return SteviaLayoutYAxisAnchor(anchor: left.anchor, constant: -right) } @available(iOS 9.0, *) @discardableResult -public func + (left: SteviaLayoutXAxisAnchor, right: CGFloat) -> SteviaLayoutXAxisAnchor { +public func + (left: SteviaLayoutXAxisAnchor, right: Double) -> SteviaLayoutXAxisAnchor { return SteviaLayoutXAxisAnchor(anchor: left.anchor, constant: right) } @available(iOS 9.0, *) @discardableResult -public func - (left: SteviaLayoutXAxisAnchor, right: CGFloat) -> SteviaLayoutXAxisAnchor { +public func - (left: SteviaLayoutXAxisAnchor, right: Double) -> SteviaLayoutXAxisAnchor { return SteviaLayoutXAxisAnchor(anchor: left.anchor, constant: -right) } diff --git a/Sources/Stevia/Stevia+Operators.swift b/Sources/Stevia/Stevia+Operators.swift index 904f6fa8..fb0d4d70 100644 --- a/Sources/Stevia/Stevia+Operators.swift +++ b/Sources/Stevia/Stevia+Operators.swift @@ -12,13 +12,13 @@ import UIKit prefix operator | @discardableResult public prefix func | (p: UIView) -> UIView { - return p.leading(0) + p.leading(0) } postfix operator | @discardableResult public postfix func | (p: UIView) -> UIView { - return p.trailing(0) + p.trailing(0) } infix operator ~ : HeightPrecedence @@ -28,22 +28,33 @@ precedencegroup HeightPrecedence { } @discardableResult -public func ~ (left: UIView, right: CGFloat) -> UIView { - return left.height(right) +public func ~ (left: UIView, right: Double) -> UIView { + left.height(right) +} + +@discardableResult +public func ~ (left: UIView, right: Int) -> UIView { + left.height(right) } @discardableResult public func ~ (left: UIView, right: SteviaPercentage) -> UIView { - return left.height(right) + left.height(right) } @discardableResult public func ~ (left: UIView, right: SteviaFlexibleMargin) -> UIView { - return left.height(right) + left.height(right) +} + +@discardableResult +public func ~ (left: [UIView], right: Double) -> [UIView] { + for l in left { l.height(right) } + return left } @discardableResult -public func ~ (left: [UIView], right: CGFloat) -> [UIView] { +public func ~ (left: [UIView], right: Int) -> [UIView] { for l in left { l.height(right) } return left } @@ -56,50 +67,70 @@ public func ~ (left: [UIView], right: SteviaFlexibleMargin) -> [UIView] { prefix operator |- @discardableResult -public prefix func |- (p: CGFloat) -> SideConstraint { +public prefix func |- (p: Double) -> SideConstraint { var s = SideConstraint() s.constant = p return s } +@discardableResult +public prefix func |- (p: Int) -> SideConstraint { + var s = SideConstraint() + s.constant = Double(p) + return s +} + @discardableResult public prefix func |- (v: UIView) -> UIView { v.leading(8) - return v } postfix operator -| @discardableResult -public postfix func -| (p: CGFloat) -> SideConstraint { +public postfix func -| (p: Double) -> SideConstraint { var s = SideConstraint() s.constant = p return s } +@discardableResult +public postfix func -| (p: Int) -> SideConstraint { + var s = SideConstraint() + s.constant = Double(p) + return s +} + @discardableResult public postfix func -| (v: UIView) -> UIView { v.trailing(8) - return v } public struct SideConstraint { - var constant: CGFloat! + var constant: Double! } public struct PartialConstraint { var view1: UIView! - var constant: CGFloat! + var constant: Double! var views: [UIView]? } @discardableResult -public func - (left: UIView, right: CGFloat) -> PartialConstraint { +public func - (left: UIView, right: Double) -> PartialConstraint { var p = PartialConstraint() p.view1 = left p.constant = right return p } +@discardableResult +public func - (left: UIView, right: Int) -> PartialConstraint { + var p = PartialConstraint() + p.view1 = left + p.constant = Double(right) + return p +} + // Side Constraints @discardableResult @@ -172,13 +203,21 @@ public func - (left: UIView, right: UIView) -> [UIView] { } @discardableResult -public func - (left: [UIView], right: CGFloat) -> PartialConstraint { +public func - (left: [UIView], right: Double) -> PartialConstraint { var p = PartialConstraint() p.constant = right p.views = left return p } +@discardableResult +public func - (left: [UIView], right: Int) -> PartialConstraint { + var p = PartialConstraint() + p.constant = Double(right) + p.views = left + return p +} + @discardableResult public func - (left: [UIView], right: UIView) -> [UIView] { let lastView = left[left.count-1] @@ -198,12 +237,12 @@ public struct Space { @discardableResult public func - (left: UIView, right: String) -> Space { - return Space(previousViews: [left]) + Space(previousViews: [left]) } @discardableResult public func - (left: [UIView], right: String) -> Space { - return Space(previousViews: left) + Space(previousViews: left) } @discardableResult diff --git a/Sources/Stevia/Stevia+Percentage.swift b/Sources/Stevia/Stevia+Percentage.swift index 96466a82..884dfa93 100644 --- a/Sources/Stevia/Stevia+Percentage.swift +++ b/Sources/Stevia/Stevia+Percentage.swift @@ -10,14 +10,18 @@ import UIKit public struct SteviaPercentage { - let value: CGFloat + let value: Double } postfix operator % -public postfix func % (v: CGFloat) -> SteviaPercentage { +public postfix func % (v: Double) -> SteviaPercentage { return SteviaPercentage(value: v) } +public postfix func % (v: Int) -> SteviaPercentage { + return SteviaPercentage(value: Double(v)) +} + public extension UIView { /** @@ -195,7 +199,7 @@ public extension UIView { let lg = UILayoutGuide() spv.addLayoutGuide(lg) let constraints = [ - lg.widthAnchor.constraint(equalTo: spv.widthAnchor, multiplier: p.value / 100), + lg.widthAnchor.constraint(equalTo: spv.widthAnchor, multiplier: CGFloat(p.value / 100.0)), lg.leadingAnchor.constraint(equalTo: spv.leadingAnchor), leadingAnchor.constraint(equalTo: lg.trailingAnchor) ] @@ -226,7 +230,7 @@ public extension UIView { let lg = UILayoutGuide() spv.addLayoutGuide(lg) let constraints = [ - lg.widthAnchor.constraint(equalTo: spv.widthAnchor, multiplier: p.value / 100), + lg.widthAnchor.constraint(equalTo: spv.widthAnchor, multiplier: CGFloat(p.value / Double(100))), lg.trailingAnchor.constraint(equalTo: spv.trailingAnchor), trailingAnchor.constraint(equalTo: lg.leadingAnchor) ] diff --git a/Sources/Stevia/Stevia+Position.swift b/Sources/Stevia/Stevia+Position.swift index c62eb683..c7c8df83 100644 --- a/Sources/Stevia/Stevia+Position.swift +++ b/Sources/Stevia/Stevia+Position.swift @@ -23,7 +23,7 @@ public extension UIView { - Returns: Itself for chaining purposes */ @discardableResult - func left(_ points: CGFloat) -> Self { + func left(_ points: Double) -> Self { return position(.left, points: points) } @@ -39,7 +39,7 @@ public extension UIView { - Returns: Itself for chaining purposes */ @discardableResult - func right(_ points: CGFloat) -> Self { + func right(_ points: Double) -> Self { return position(.right, points: -points) } @@ -55,7 +55,7 @@ public extension UIView { - Returns: Itself for chaining purposes */ @discardableResult - func top(_ points: CGFloat) -> Self { + func top(_ points: Double) -> Self { return position(.top, points: points) } @@ -71,7 +71,7 @@ public extension UIView { - Returns: Itself for chaining purposes */ @discardableResult - func bottom(_ points: CGFloat) -> Self { + func bottom(_ points: Double) -> Self { return position(.bottom, points: -points) } @@ -170,7 +170,7 @@ public extension UIView { */ @discardableResult - func leading(_ points: CGFloat) -> UIView { + func leading(_ points: Double) -> UIView { return position(.leading, points: points) } @@ -191,7 +191,7 @@ public extension UIView { - Returns: itself for chaining purposes */ @discardableResult - func trailing(_ points: CGFloat) -> UIView { + func trailing(_ points: Double) -> UIView { return position(.trailing, points: -points) } @@ -208,7 +208,7 @@ public extension UIView { fileprivate func position(_ position: NSLayoutConstraint.Attribute, relatedBy: NSLayoutConstraint.Relation = .equal, - points: CGFloat) -> Self { + points: Double) -> Self { if let spv = superview { let c = constraint(item: self, attribute: position, relatedBy: relatedBy, diff --git a/Sources/Stevia/Stevia+Size.swift b/Sources/Stevia/Stevia+Size.swift index f2122b8f..f316c3d9 100644 --- a/Sources/Stevia/Stevia+Size.swift +++ b/Sources/Stevia/Stevia+Size.swift @@ -27,12 +27,56 @@ public extension UIView { */ @discardableResult - func size(_ points: CGFloat) -> Self { + func size(_ points: Double) -> Self { width(points) height(points) return self } + /** + Adds an Autolayout constraint for sizing the view. + + ``` + image.size(100) + image.size(100%) + + // is equivalent to + + image.width(100).height(100) + ``` + + - Returns: Itself, enabling chaining, + + */ + @discardableResult + func size(_ points: Int) -> Self { + size(Double(points)) + } + + /** + Adds an Autolayout constraint for setting the view's height. + + ``` + image.height(100) + + // is equivalent to + + image ~ 100 + + // Flexible margins + image.height(<=100) + image.height(>=100) + image.height(100%) + ``` + + - Returns: Itself, enabling chaining, + + */ + @discardableResult + func height(_ points: Double) -> Self { + size(.height, points: points) + } + /** Adds an Autolayout constraint for setting the view's height. @@ -53,8 +97,26 @@ public extension UIView { */ @discardableResult - func height(_ points: CGFloat) -> Self { - return size(.height, points: points) + func height(_ points: Int) -> Self { + size(.height, points: Double(points)) + } + + /** + Adds an Autolayout constraint for setting the view's width. + + ``` + image.width(100) + image.width(<=100) + image.width(>=100) + image.width(100%) + ``` + + - Returns: Itself, enabling chaining, + + */ + @discardableResult + func width(_ points: Double) -> Self { + size(.width, points: points) } /** @@ -71,8 +133,8 @@ public extension UIView { */ @discardableResult - func width(_ points: CGFloat) -> Self { - return size(.width, points: points) + func width(_ points: Int) -> Self { + size(.width, points: Double(points)) } /** @@ -119,7 +181,7 @@ public extension UIView { fileprivate func size(_ attribute: NSLayoutConstraint.Attribute, relatedBy: NSLayoutConstraint.Relation = .equal, - points: CGFloat) -> Self { + points: Double) -> Self { let c = constraint(item: self, attribute: attribute, relatedBy: relatedBy, diff --git a/Sources/Stevia/Stevia+Stacks.swift b/Sources/Stevia/Stevia+Stacks.swift index b85598aa..5f1b0cd1 100644 --- a/Sources/Stevia/Stevia+Stacks.swift +++ b/Sources/Stevia/Stevia+Stacks.swift @@ -6,6 +6,49 @@ // Copyright © 2016 Sacha Durand Saint Omer. All rights reserved. // +//enum SteviaLayoutItemType { +// +//} + +public protocol SteviaLayoutItem { + var any: Any {get} +} + +extension SteviaLayoutItem { + public var any: Any { self } +} +extension UIView: SteviaLayoutItem {} +extension Int: SteviaLayoutItem {} +extension Double: SteviaLayoutItem {} +extension String: SteviaLayoutItem {} +extension FlexibleSpace: SteviaLayoutItem {} +extension SteviaFlexibleMargin: SteviaLayoutItem {} +extension SteviaPercentage: SteviaLayoutItem {} +extension Array: SteviaLayoutItem where Element: UIView {} + +public struct FlexibleSpace { + public init() {} +} + + +@_functionBuilder public struct SteviaLayoutBuilder { + public static func buildBlock(_ content: SteviaLayoutItem...) -> [SteviaLayoutItem] { + return content + } +} + +public extension UIView { + @discardableResult + func Layout(@SteviaLayoutBuilder content: () -> [SteviaLayoutItem]) -> UIView { + let subviews = content() + + let anys = subviews.map { $0.any } + layout(anys) + return self + } +} + + #if canImport(UIKit) import UIKit @@ -32,6 +75,7 @@ public extension UIView { ) ``` */ + @available(*, deprecated, message: "Use Layout { } function builder instead.") @discardableResult func layout(_ objects: Any...) -> [UIView] { return layout(objects) @@ -39,7 +83,7 @@ public extension UIView { @discardableResult func layout(_ objects: [Any]) -> [UIView] { - var previousMargin: CGFloat? + var previousMargin: Double? var previousFlexibleMargin: SteviaFlexibleMargin? var previousPercentMargin: SteviaPercentage? @@ -85,11 +129,12 @@ public extension UIView { if let vx = objects[i-2] as? UIView { // Add layout guide to suport %-based spaces. let percent = ppm.value / 100 + let lg = UILayoutGuide() addLayoutGuide(lg) NSLayoutConstraint.activate([ lg.topAnchor.constraint(equalTo: vx.bottomAnchor), - lg.heightAnchor.constraint(equalTo: heightAnchor, multiplier: percent), + lg.heightAnchor.constraint(equalTo: heightAnchor, multiplier: CGFloat(percent)), v.topAnchor.constraint(equalTo: lg.bottomAnchor) ]) } @@ -104,7 +149,7 @@ public extension UIView { case let v as UIView: viewLogic(v) case is Int, is Double, is CGFloat: - let m = cgFloatMarginFromObject(o) + let m = doubleMarginFromObject(o) previousMargin = m // Store margin for next pass if i != 0 && i == (objects.count - 1) { //Last Margin, Bottom @@ -145,14 +190,14 @@ public extension UIView { return objects.map {$0 as? UIView }.compactMap {$0} } - fileprivate func cgFloatMarginFromObject(_ o: Any) -> CGFloat { - var m: CGFloat = 0 + fileprivate func doubleMarginFromObject(_ o: Any) -> Double { + var m: Double = 0 if let i = o as? Int { - m = CGFloat(i) + m = Double(i) } else if let d = o as? Double { - m = CGFloat(d) - } else if let cg = o as? CGFloat { - m = cg + m = d + } else if let cg = o as? Double { + m = Double(cg) } return m } @@ -174,12 +219,12 @@ public extension UIView { } @discardableResult - fileprivate func stackV(m points: CGFloat = 0, v: UIView) -> UIView { + fileprivate func stackV(m points: Double = 0, v: UIView) -> UIView { return stack(.vertical, points: points, v: v) } fileprivate func stack(_ axis: NSLayoutConstraint.Axis, - points: CGFloat = 0, v: UIView) -> UIView { + points: Double = 0, v: UIView) -> UIView { let a: NSLayoutConstraint.Attribute = axis == .vertical ? .top : .left let b: NSLayoutConstraint.Attribute = axis == .vertical ? .bottom : .right if let spv = superview { diff --git a/Tests/SteviaTests/BaselineTests.swift b/Tests/SteviaTests/BaselineTests.swift index 4294d220..5c6a5344 100644 --- a/Tests/SteviaTests/BaselineTests.swift +++ b/Tests/SteviaTests/BaselineTests.swift @@ -13,8 +13,10 @@ class BaselineTests: XCTestCase { var win: UIWindow! var ctrler: UIViewController! - var label1: UILabel! - var label2: UILabel! + var label1 = UILabel() + var label2 = UILabel() + + override func setUp() { win = UIWindow(frame: UIScreen.main.bounds) @@ -22,10 +24,11 @@ class BaselineTests: XCTestCase { win.rootViewController = ctrler label1 = UILabel() label2 = UILabel() - ctrler.view.sv( - label1, + + ctrler.view.Subviews { + label1 label2 - ) + } } func testAlignLastBaselines() { diff --git a/Tests/SteviaTests/CenterTests.swift b/Tests/SteviaTests/CenterTests.swift index e9ad39c0..212c975d 100644 --- a/Tests/SteviaTests/CenterTests.swift +++ b/Tests/SteviaTests/CenterTests.swift @@ -22,7 +22,7 @@ class CenterTests: XCTestCase { ctrler = UIViewController() win.rootViewController = ctrler v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } verifyViewHasDefaultValues() } diff --git a/Tests/SteviaTests/EquationTests.swift b/Tests/SteviaTests/EquationTests.swift index 7a47553c..159770f9 100644 --- a/Tests/SteviaTests/EquationTests.swift +++ b/Tests/SteviaTests/EquationTests.swift @@ -27,7 +27,7 @@ class EquationTests: XCTestCase { func testTop() { let v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } v.Top == ctrler.view.Top + 10 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, 10) @@ -35,7 +35,7 @@ class EquationTests: XCTestCase { func testTopReflexive() { let v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } ctrler.view.Top + 10 == v.Top ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, 10) @@ -43,7 +43,7 @@ class EquationTests: XCTestCase { func testTopGreaterOrEqual() { let v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } v.Top >= ctrler.view.Top + 10 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, 10) @@ -51,7 +51,7 @@ class EquationTests: XCTestCase { func testTopLessThanOrEqual() { let v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } v.Top <= ctrler.view.Top + 10 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, 10) @@ -59,7 +59,7 @@ class EquationTests: XCTestCase { func testBottom() { let v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } v.Bottom == ctrler.view.Bottom - 23 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, ctrler.view.frame.height - 23) @@ -67,7 +67,7 @@ class EquationTests: XCTestCase { func testBottomReflexive() { let v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } ctrler.view.Bottom - 23 == v.Bottom ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, ctrler.view.frame.height - 23) @@ -75,7 +75,7 @@ class EquationTests: XCTestCase { func testBottomGreaterOrEqual() { let v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } v.Bottom >= ctrler.view.Bottom - 23 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, ctrler.view.frame.height - 23) @@ -83,7 +83,7 @@ class EquationTests: XCTestCase { func testBottomLessOrEqual() { let v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } v.Bottom <= ctrler.view.Bottom - 23 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, ctrler.view.frame.height - 23) @@ -91,7 +91,7 @@ class EquationTests: XCTestCase { func testLeft() { let v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } v.Left == ctrler.view.Left + 72 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.x, 72) @@ -99,7 +99,7 @@ class EquationTests: XCTestCase { func testLeftReflexive() { let v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } ctrler.view.Left + 72 == v.Left ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.x, 72) @@ -107,7 +107,7 @@ class EquationTests: XCTestCase { func testLeftGreaterOrEqual() { let v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } v.Left >= ctrler.view.Left + 72 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.x, 72) @@ -115,7 +115,7 @@ class EquationTests: XCTestCase { func testLeftLessOrEqual() { let v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } v.Left <= ctrler.view.Left + 72 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.x, 72) @@ -123,7 +123,7 @@ class EquationTests: XCTestCase { func testRight() { let v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } v.Right == ctrler.view.Right - 13 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.x, ctrler.view.frame.width - 13) @@ -131,7 +131,7 @@ class EquationTests: XCTestCase { func testRightReflexive() { let v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } ctrler.view.Right - 13 == v.Right ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.x, ctrler.view.frame.width - 13) @@ -139,7 +139,7 @@ class EquationTests: XCTestCase { func testRightGreaterOrEqual() { let v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } v.Right >= ctrler.view.Right - 13 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.x, ctrler.view.frame.width - 13) @@ -147,7 +147,7 @@ class EquationTests: XCTestCase { func testRightLessOrEqual() { let v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } v.Right >= ctrler.view.Right - 13 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.x, ctrler.view.frame.width - 13) @@ -155,7 +155,7 @@ class EquationTests: XCTestCase { func testWidth() { let v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } v.Width == ctrler.view.Width - 52 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.width, ctrler.view.frame.width - 52) @@ -163,7 +163,7 @@ class EquationTests: XCTestCase { func testWidthReflexive() { let v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } ctrler.view.Width - 52 == v.Width ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.width, ctrler.view.frame.width - 52) @@ -171,7 +171,7 @@ class EquationTests: XCTestCase { func testWidthGreaterOrEqual() { let v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } v.Width >= ctrler.view.Width - 52 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.width, ctrler.view.frame.width - 52) @@ -179,7 +179,7 @@ class EquationTests: XCTestCase { func testWidthLessOrEqual() { let v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } v.Width <= ctrler.view.Width - 52 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.width, 0) @@ -187,7 +187,7 @@ class EquationTests: XCTestCase { func testHeight() { let v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } v.Height == ctrler.view.Height + 34 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.height, ctrler.view.frame.height + 34) @@ -195,7 +195,7 @@ class EquationTests: XCTestCase { func testHeightReflexive() { let v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } ctrler.view.Height + 34 == v.Height ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.height, ctrler.view.frame.height + 34) @@ -203,7 +203,7 @@ class EquationTests: XCTestCase { func testHeightGreaterOrEqual() { let v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } v.Height >= ctrler.view.Height - 34 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.height, ctrler.view.frame.height - 34) @@ -211,7 +211,7 @@ class EquationTests: XCTestCase { func testHeightLessOrEqual() { let v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } v.Height <= ctrler.view.Height - 34 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.height, 0) @@ -221,7 +221,7 @@ class EquationTests: XCTestCase { func testSingleValueTop() { let v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } v.Top == 10 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, 10) @@ -229,7 +229,7 @@ class EquationTests: XCTestCase { func testSingleValueTopGreaterOrEqual() { let v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } v.Top >= 10 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, 10) @@ -237,7 +237,7 @@ class EquationTests: XCTestCase { func testSingleValueLessOrEqual() { let v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } v.Top <= 10 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, 10) @@ -245,7 +245,7 @@ class EquationTests: XCTestCase { func testSingleValueBottom() { let v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } v.Bottom == 23 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, ctrler.view.frame.height - 23) @@ -253,7 +253,7 @@ class EquationTests: XCTestCase { func testSingleValueBottomGreaterOrEqual() { let v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } v.Bottom >= 23 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, ctrler.view.frame.height - 23) @@ -261,7 +261,7 @@ class EquationTests: XCTestCase { func testSingleValueBottomLessOrEqual() { let v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } v.Bottom <= 23 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, ctrler.view.frame.height - 23) @@ -269,7 +269,7 @@ class EquationTests: XCTestCase { func testSingleValueLeft() { let v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } v.Left == 72 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.x, 72) @@ -277,7 +277,7 @@ class EquationTests: XCTestCase { func testSingleValueLeftGreaterOrEqual() { let v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } v.Left >= 72 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.x, 72) @@ -285,7 +285,7 @@ class EquationTests: XCTestCase { func testSingleValueLeftLessOrEqual() { let v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } v.Left <= 72 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.x, 72) @@ -293,7 +293,7 @@ class EquationTests: XCTestCase { func testSingleValueRight() { let v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } v.Right == 13 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.x, ctrler.view.frame.width - 13) @@ -301,7 +301,7 @@ class EquationTests: XCTestCase { func testSingleValueRightGreaterOrEqual() { let v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } v.Right >= 13 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.x, ctrler.view.frame.width - 13) @@ -309,7 +309,7 @@ class EquationTests: XCTestCase { func testSingleValueRightLessOrEqual() { let v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } v.Right <= 13 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.x, ctrler.view.frame.width - 13) @@ -317,7 +317,7 @@ class EquationTests: XCTestCase { func testSingleValueWidth() { let v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } v.Width == 23 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.width, 23) @@ -325,7 +325,7 @@ class EquationTests: XCTestCase { func testSingleValueWidthGreaterOrEqual() { let v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } v.Width >= 23 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.width, 23) @@ -333,7 +333,7 @@ class EquationTests: XCTestCase { func testSingleValueWidthLessOrEqual() { let v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } v.centerInContainer() // There is a bug where we need to have a x/y placement for size to be accurate. v.Width <= 23 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in @@ -342,7 +342,7 @@ class EquationTests: XCTestCase { func testSingleValueHeight() { let v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } v.Height == 94 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.height, 94) @@ -350,7 +350,7 @@ class EquationTests: XCTestCase { func testSingleValueHeightGreaterOrEqual() { let v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } v.Height >= 94 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.height, 94) @@ -358,7 +358,7 @@ class EquationTests: XCTestCase { func testSingleValueHeightLessOrEqual() { let v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } v.centerInContainer() // There is a bug where we need to have a x/y placement for size to be accurate. v.Height <= 94 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in @@ -368,11 +368,11 @@ class EquationTests: XCTestCase { func testScrollView() { let scrollView = UIScrollView() let contentView = UIView() - ctrler.view.sv( - scrollView.sv( + ctrler.view.Subviews { + scrollView.Subviews { contentView - ) - ) + } + } scrollView.fillContainer() contentView.Width == ctrler.view.Width ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in @@ -382,11 +382,11 @@ class EquationTests: XCTestCase { func testScrollViewReflexive() { let scrollView = UIScrollView() let contentView = UIView() - ctrler.view.sv( - scrollView.sv( + ctrler.view.Subviews { + scrollView.Subviews { contentView - ) - ) + } + } scrollView.fillContainer() ctrler.view.Width == contentView.Width ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in @@ -399,12 +399,12 @@ class EquationTests: XCTestCase { let field = UIView() let dropdown = UIView() - ctrler.view.sv( - box.sv( + ctrler.view.Subviews { + box.Subviews { field - ), + } dropdown - ) + } box.fillContainer(60) |-field-|.top(1).height(50)//centerVertically() @@ -427,12 +427,12 @@ class EquationTests: XCTestCase { let field = UIView() let dropdown = UIView() - ctrler.view.sv( - box.sv( + ctrler.view.Subviews { + box.Subviews { field - ), + } dropdown - ) + } box.fillContainer(60) |-field-|.top(1).height(50)//centerVertically() diff --git a/Tests/SteviaTests/FillTests.swift b/Tests/SteviaTests/FillTests.swift index 75c369d2..3ad2c946 100644 --- a/Tests/SteviaTests/FillTests.swift +++ b/Tests/SteviaTests/FillTests.swift @@ -27,21 +27,22 @@ class FillTests: XCTestCase { func testFillContainer() { let b = UIButton() - ctrler.view.sv(b) + ctrler.view.Subviews { b } b.fillContainer() ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(ctrler.view.frame, b.frame) } + func testFillContainerWithPadding() { - let padding: CGFloat = 10.0 + let padding = 10.0 let b = UIButton() - ctrler.view.sv(b) + ctrler.view.Subviews { b } b.fillContainer(padding) ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in - XCTAssertEqual(ctrler.view.frame.height, b.frame.height + padding * 2, + XCTAssertEqual(ctrler.view.frame.height, b.frame.height + CGFloat(padding) * 2, accuracy: CGFloat(Float.ulpOfOne)) - XCTAssertEqual(ctrler.view.frame.width, b.frame.width + padding * 2, + XCTAssertEqual(ctrler.view.frame.width, b.frame.width + CGFloat(padding) * 2, accuracy: CGFloat(Float.ulpOfOne)) } } diff --git a/Tests/SteviaTests/FlexibleMarginTests.swift b/Tests/SteviaTests/FlexibleMarginTests.swift index 09b1ba37..1c36f60a 100644 --- a/Tests/SteviaTests/FlexibleMarginTests.swift +++ b/Tests/SteviaTests/FlexibleMarginTests.swift @@ -21,7 +21,7 @@ class FlexibleMarginTests: XCTestCase { ctrler = UIViewController() win.rootViewController = ctrler v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } v.size(100.0) } @@ -230,7 +230,7 @@ class FlexibleMarginTests: XCTestCase { let v1 = UIView() let v2 = UIView() v.removeFromSuperview() - ctrler.view.sv(v1, v2) + ctrler.view.Subviews { v1; v2 } for view in ctrler.view.subviews { XCTAssertEqual(view.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(view.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) @@ -256,7 +256,10 @@ class FlexibleMarginTests: XCTestCase { let v1 = UIView() let v2 = UIView() v.removeFromSuperview() - ctrler.view.sv(v1, v2) + ctrler.view.Subviews { + v1 + v2 + } for view in ctrler.view.subviews { XCTAssertEqual(view.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(view.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) @@ -282,7 +285,10 @@ class FlexibleMarginTests: XCTestCase { let v1 = UIView() let v2 = UIView() v.removeFromSuperview() - ctrler.view.sv(v1, v2) + ctrler.view.Subviews { + v1 + v2 + } for view in ctrler.view.subviews { XCTAssertEqual(view.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(view.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) @@ -308,7 +314,10 @@ class FlexibleMarginTests: XCTestCase { let v1 = UIView() let v2 = UIView() v.removeFromSuperview() - ctrler.view.sv(v1, v2) + ctrler.view.Subviews { + v1 + v2 + } for view in ctrler.view.subviews { XCTAssertEqual(view.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(view.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) diff --git a/Tests/SteviaTests/FullLayoutTests.swift b/Tests/SteviaTests/FullLayoutTests.swift index 9c3ff0c6..6eff67b9 100644 --- a/Tests/SteviaTests/FullLayoutTests.swift +++ b/Tests/SteviaTests/FullLayoutTests.swift @@ -21,34 +21,35 @@ class TestView: UIView { convenience init() { self.init(frame: CGRect.zero) - sv( - email, - password, + Subviews { + email + password login - ) - - layout( - 100, - |-email-22-| ~ 10%, - 20, - |password.width(54) ~ 47, - "", - login.centerHorizontally() ~ 99, + } + + Layout { + 100 + |-email-22-| ~ 10% + 20 + |password.width(54) ~ 47 + >=0 + login.centerHorizontally() ~ 99 7 - ) + } - sv( - view1, + Subviews { + view1 view2 - ) + } - layout( - 10%, - |view1| ~ 20, - 33%, - |view2|, + Layout { + 10% + |view1| ~ 20 + 33% + |view2| 20% - ) + } + } } diff --git a/Tests/SteviaTests/GetConstraintsTests.swift b/Tests/SteviaTests/GetConstraintsTests.swift index 2873d16f..778f9fde 100644 --- a/Tests/SteviaTests/GetConstraintsTests.swift +++ b/Tests/SteviaTests/GetConstraintsTests.swift @@ -17,7 +17,7 @@ class GetConstraintsTests: XCTestCase { override func setUp() { spv = UIView() v = UIView() - spv.sv(v) + spv.Subviews { v } } func testCanGetLeftConstraint() { diff --git a/Tests/SteviaTests/HierarchyTests.swift b/Tests/SteviaTests/HierarchyTests.swift index 1edd00ad..40317633 100644 --- a/Tests/SteviaTests/HierarchyTests.swift +++ b/Tests/SteviaTests/HierarchyTests.swift @@ -19,7 +19,7 @@ class HierarchyTests: XCTestCase { super.tearDown() } - func testSv() { + func testLegacySv() { let view = UIView() let v1 = UIView() let v2 = UIView() @@ -34,7 +34,7 @@ class HierarchyTests: XCTestCase { XCTAssertFalse(v2.translatesAutoresizingMaskIntoConstraints) } - func testTableViewCellSV() { + func testLegacyTableViewCellSV() { let cell = UITableViewCell() let v1 = UIView() let v2 = UIView() @@ -49,7 +49,7 @@ class HierarchyTests: XCTestCase { XCTAssertFalse(v2.translatesAutoresizingMaskIntoConstraints) } - func testCollectionViewCellSV() { + func testLegacyCollectionViewCellSV() { let cell = UICollectionViewCell() let v1 = UIView() let v2 = UIView() @@ -80,7 +80,6 @@ class HierarchyTests: XCTestCase { XCTAssertFalse(v1.translatesAutoresizingMaskIntoConstraints) XCTAssertFalse(v2.translatesAutoresizingMaskIntoConstraints) } - func testTableViewCellSubviews() { let cell = UITableViewCell() @@ -113,4 +112,30 @@ class HierarchyTests: XCTestCase { XCTAssertFalse(v1.translatesAutoresizingMaskIntoConstraints) XCTAssertFalse(v2.translatesAutoresizingMaskIntoConstraints) } + + func testSubviewsCanBeNested() { + let view = UIView() + let v1 = UIView() + let v2 = UIView() + let v3 = UIView() + let v4 = UIView() + view.Subviews { + v1.Subviews { + v3 + v4 + } + v2 + } + XCTAssertEqual(view.subviews.count, 2) + XCTAssertTrue(view.subviews.contains(v1)) + XCTAssertTrue(view.subviews.contains(v2)) + XCTAssertEqual(v1.subviews.count, 2) + XCTAssertTrue(v1.subviews.contains(v3)) + XCTAssertTrue(v1.subviews.contains(v4)) + + XCTAssertFalse(v1.translatesAutoresizingMaskIntoConstraints) + XCTAssertFalse(v2.translatesAutoresizingMaskIntoConstraints) + XCTAssertFalse(v3.translatesAutoresizingMaskIntoConstraints) + XCTAssertFalse(v4.translatesAutoresizingMaskIntoConstraints) + } } diff --git a/Tests/SteviaTests/LayoutTests.swift b/Tests/SteviaTests/LayoutTests.swift index 47ab9f4b..79add5f5 100644 --- a/Tests/SteviaTests/LayoutTests.swift +++ b/Tests/SteviaTests/LayoutTests.swift @@ -21,7 +21,7 @@ class LayoutTests: XCTestCase { ctrler = UIViewController() win.rootViewController = ctrler v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { v } verifyViewHasDefaultValues() } @@ -172,7 +172,11 @@ class LayoutTests: XCTestCase { let v2 = UIView() let v3 = UIView() v.removeFromSuperview() - ctrler.view.sv(v1, v2, v3) + ctrler.view.Subviews { + v1 + v2 + v3 + } for view in ctrler.view.subviews { XCTAssertEqual(view.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(view.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) @@ -193,7 +197,10 @@ class LayoutTests: XCTestCase { let v1 = UIView() let v2 = UIView() v.removeFromSuperview() - ctrler.view.sv(v1, v2) + ctrler.view.Subviews { + v1 + v2 + } for view in ctrler.view.subviews { XCTAssertEqual(view.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(view.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) @@ -219,7 +226,10 @@ class LayoutTests: XCTestCase { let v1 = UIView() let v2 = UIView() v.removeFromSuperview() - ctrler.view.sv(v1, v2) + ctrler.view.Subviews{ + v1 + v2 + } for view in ctrler.view.subviews { XCTAssertEqual(view.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(view.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) @@ -244,7 +254,10 @@ class LayoutTests: XCTestCase { let v1 = UIView() let v2 = UIView() v.removeFromSuperview() - ctrler.view.sv(v1, v2) + ctrler.view.Subviews { + v1 + v2 + } for view in ctrler.view.subviews { XCTAssertEqual(view.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(view.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) @@ -270,7 +283,10 @@ class LayoutTests: XCTestCase { let v1 = UIView() let v2 = UIView() v.removeFromSuperview() - ctrler.view.sv(v1, v2) + ctrler.view.Subviews { + v1 + v2 + } for view in ctrler.view.subviews { XCTAssertEqual(view.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(view.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) @@ -294,7 +310,10 @@ class LayoutTests: XCTestCase { let v1 = UIView() let v2 = UIView() v.removeFromSuperview() - ctrler.view.sv(v1, v2) + ctrler.view.Subviews { + v1 + v2 + } for view in ctrler.view.subviews { XCTAssertEqual(view.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(view.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) @@ -325,7 +344,10 @@ class LayoutTests: XCTestCase { let v1 = UIView() let v2 = UIView() v.removeFromSuperview() - ctrler.view.sv(v1, v2) + ctrler.view.Subviews { + v1 + v2 + } for view in ctrler.view.subviews { XCTAssertEqual(view.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(view.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) @@ -353,7 +375,11 @@ class LayoutTests: XCTestCase { let v2 = UIView() let v3 = UIView() v.removeFromSuperview() - ctrler.view.sv(v1, v2, v3) + ctrler.view.Subviews { + v1 + v2 + v3 + } for view in ctrler.view.subviews { XCTAssertEqual(view.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(view.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) @@ -386,7 +412,11 @@ class LayoutTests: XCTestCase { let v2 = UIView() let v3 = UIView() v.removeFromSuperview() - ctrler.view.sv(v1, v2, v3) + ctrler.view.Subviews { + v1 + v2 + v3 + } for view in ctrler.view.subviews { XCTAssertEqual(view.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(view.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) @@ -420,7 +450,11 @@ class LayoutTests: XCTestCase { let v2 = UIView() let v3 = UIView() v.removeFromSuperview() - ctrler.view.sv(v1, v2, v3) + ctrler.view.Subviews { + v1 + v2 + v3 + } for view in ctrler.view.subviews { XCTAssertEqual(view.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(view.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) @@ -452,7 +486,10 @@ class LayoutTests: XCTestCase { let v1 = UIView() let v2 = UIView() v.removeFromSuperview() - ctrler.view.sv(v1, v2) + ctrler.view.Subviews { + v1 + v2 + } for view in ctrler.view.subviews { XCTAssertEqual(view.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(view.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) @@ -480,7 +517,10 @@ class LayoutTests: XCTestCase { let v1 = UIView() let v2 = UIView() v.removeFromSuperview() - ctrler.view.sv(v1, v2) + ctrler.view.Subviews { + v1 + v2 + } for view in ctrler.view.subviews { XCTAssertEqual(view.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(view.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) @@ -508,7 +548,7 @@ class LayoutTests: XCTestCase { let v2 = UIView() let v3 = UIView() v.removeFromSuperview() - ctrler.view.sv(v1, v2, v3) + ctrler.view.Subviews { v1; v2; v3 } for view in ctrler.view.subviews { XCTAssertEqual(view.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(view.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) diff --git a/Tests/SteviaTests/PositionTests.swift b/Tests/SteviaTests/PositionTests.swift index fdd189bb..edfc88ea 100644 --- a/Tests/SteviaTests/PositionTests.swift +++ b/Tests/SteviaTests/PositionTests.swift @@ -21,7 +21,7 @@ class PositionTests: XCTestCase { ctrler = UIViewController() win.rootViewController = ctrler v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews {v } v.size(100.0) } diff --git a/Tests/SteviaTests/SizeTests.swift b/Tests/SteviaTests/SizeTests.swift index 219c9e07..72a56edd 100644 --- a/Tests/SteviaTests/SizeTests.swift +++ b/Tests/SteviaTests/SizeTests.swift @@ -21,7 +21,9 @@ class SizeTests: XCTestCase { ctrler = UIViewController() win.rootViewController = ctrler v = UIView() - ctrler.view.sv(v) + ctrler.view.Subviews { + v + } } override func tearDown() { @@ -68,13 +70,14 @@ class SizeTests: XCTestCase { } func testEqualSizes() { - let width: CGFloat = 24 - let height: CGFloat = 267 + let width = 24.0 + let height = 267.0 let v1 = UIView() let v2 = UIView() - ctrler.view.sv( - v1, v2 - ) + ctrler.view.Subviews { + v1 + v2 + } v1.height(height) v1.width(width) equal(sizes: [v1, v2]) @@ -84,13 +87,14 @@ class SizeTests: XCTestCase { } func testVariadicEqualSizes() { - let width: CGFloat = 24 - let height: CGFloat = 267 + let width = 24.0 + let height = 267.0 let v1 = UIView() let v2 = UIView() - ctrler.view.sv( - v1, v2 - ) + ctrler.view.Subviews { + v1 + v2 + } v1.height(height) v1.width(width) equal(sizes: v1, v2) @@ -102,14 +106,18 @@ class SizeTests: XCTestCase { func testFollwEdges() { let v1 = UIView() let v2 = UIView() - ctrler.view.sv( - v1, v2 - ) + ctrler.view.Subviews { + v1 + v2 + } - ctrler.view.layout( - 10, + let test = ctrler.view + + test!.Layout { + 10 |-20-v1| ~ 32 - ) + } + ctrler.view.layoutIfNeeded() @@ -161,8 +169,13 @@ class SizeTests: XCTestCase { v.removeFromSuperview() v.height(80) v.width(80) - ctrler.view.sv(v) - ctrler.view.layout(0, |v) + ctrler.view?.Subviews { v } + + let view = ctrler.view + view?.Layout { + 0 + |v + } ctrler.view.layoutIfNeeded() XCTAssertEqual(v.frame.width, 80, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(v.frame.height, 80, accuracy: CGFloat(Float.ulpOfOne)) From 6d7620036b395a1a085368c837c1cf9711172846 Mon Sep 17 00:00:00 2001 From: S4cha Date: Thu, 2 Apr 2020 10:00:28 +0200 Subject: [PATCH 03/12] WIP Start using BinaryFloatingPoint & BinaryInteger to support all types --- Sources/Stevia/Stevia+Alignment.swift | 2 +- Sources/Stevia/Stevia+Center.swift | 62 +++++++++++++++------ Sources/Stevia/Stevia+Equation.swift | 35 ++++++++++-- Sources/Stevia/Stevia+Fill.swift | 62 ++++++++++++++++----- Sources/Stevia/Stevia+Position.swift | 22 +++++++- Sources/Stevia/Stevia+Size.swift | 10 ++-- Tests/SteviaTests/CenterTests.swift | 80 +++++++++++++++++---------- Tests/SteviaTests/EquationTests.swift | 2 +- Tests/SteviaTests/FillTests.swift | 2 +- Tests/SteviaTests/SizeTests.swift | 9 +++ 10 files changed, 214 insertions(+), 72 deletions(-) diff --git a/Sources/Stevia/Stevia+Alignment.swift b/Sources/Stevia/Stevia+Alignment.swift index fe6b4d74..0a8c2262 100644 --- a/Sources/Stevia/Stevia+Alignment.swift +++ b/Sources/Stevia/Stevia+Alignment.swift @@ -148,7 +148,7 @@ private func align(_ axis: NSLayoutConstraint.Axis, views: [UIView]) { } } -private func align(_ axis: NSLayoutConstraint.Axis, v1: UIView, with v2: UIView, offset: Double) { +func align(_ axis: NSLayoutConstraint.Axis, v1: UIView, with v2: UIView, offset: Double) { if let spv = v1.superview { let center: NSLayoutConstraint.Attribute = axis == .horizontal ? .centerY : .centerX let c = constraint(item: v1, attribute: center, toItem: v2, constant: offset) diff --git a/Sources/Stevia/Stevia+Center.swift b/Sources/Stevia/Stevia+Center.swift index cb03bf93..fb3c783f 100644 --- a/Sources/Stevia/Stevia+Center.swift +++ b/Sources/Stevia/Stevia+Center.swift @@ -34,6 +34,7 @@ public extension UIView { ``` button.centerHorizontally() + button.centerHorizontally(offset: 40) ``` - Returns: Itself, enabling chaining, @@ -41,17 +42,50 @@ public extension UIView { */ @discardableResult func centerHorizontally() -> Self { + centerHorizontally(offset: 0) + } + + /** + Centers the view horizontally (X axis) in its container. + + ``` + button.centerHorizontally() + button.centerHorizontally(offset: 40) + ``` + + - Returns: Itself, enabling chaining, + + */ + @discardableResult + func centerHorizontally(offset: T) -> Self { if let spv = superview { - align(vertically: self, spv) + align(.vertical, v1: self, with: spv, offset: Double(offset)) } return self } + /** + Centers the view horizontally (X axis) in its container. + + ``` + button.centerHorizontally() + button.centerHorizontally(offset: 40) + ``` + + - Returns: Itself, enabling chaining, + + */ + @discardableResult + func centerHorizontally(offset: T) -> Self { + centerHorizontally(offset: Double(offset)) + } + /** Centers the view vertically (Y axis) in its container. ``` button.centerVertically() + button.centerVertically(offset: 40) ``` - Returns: Itself, enabling chaining, @@ -59,46 +93,42 @@ public extension UIView { */ @discardableResult func centerVertically() -> Self { - if let spv = superview { - align(horizontally: self, spv) - } - return self + centerVertically(offset: 0) } /** - Centers the view horizontally (X axis) in its container, with an offset + Centers the view vertically (Y axis) in its container. ``` - button.centerHorizontally(40) + button.centerVertically() + button.centerVertically(offset: 40) ``` - Returns: Itself, enabling chaining, */ @discardableResult - func centerHorizontally(_ offset: Double) -> Self { + func centerVertically(offset: T) -> Self { if let spv = superview { - alignVertically(self, with: spv, offset: offset) + align(.horizontal, v1: self, with: spv, offset: Double(offset)) } return self } /** - Centers the view vertically (Y axis) in its container, with an offset + Centers the view vertically (Y axis) in its container. ``` - button.centerVertically(40) + button.centerVertically() + button.centerVertically(offset: 40) ``` - Returns: Itself, enabling chaining, */ @discardableResult - func centerVertically(_ offset: Double) -> Self { - if let spv = superview { - alignHorizontally(self, with: spv, offset: offset) - } - return self + func centerVertically(offset: T) -> Self { + centerVertically(offset: Double(offset)) } } #endif diff --git a/Sources/Stevia/Stevia+Equation.swift b/Sources/Stevia/Stevia+Equation.swift index cc45fb34..770c23e7 100644 --- a/Sources/Stevia/Stevia+Equation.swift +++ b/Sources/Stevia/Stevia+Equation.swift @@ -184,27 +184,52 @@ private func applyRelation(left: SteviaAttribute, right: SteviaAttribute, relate @discardableResult public func + (left: SteviaAttribute, right: Double) -> SteviaAttribute { - return SteviaAttribute(view: left.view, attribute: left.attribute, constant: right, multiplier: left.multiplier) + SteviaAttribute(view: left.view, attribute: left.attribute, constant: right, multiplier: left.multiplier) +} + +@discardableResult +public func + (left: SteviaAttribute, right: Int) -> SteviaAttribute { + left + Double(right) } @discardableResult public func - (left: SteviaAttribute, right: Double) -> SteviaAttribute { - return SteviaAttribute(view: left.view, attribute: left.attribute, constant: -right, multiplier: left.multiplier) + SteviaAttribute(view: left.view, attribute: left.attribute, constant: -right, multiplier: left.multiplier) +} + +@discardableResult +public func - (left: SteviaAttribute, right: Int) -> SteviaAttribute { + left - Double(right) } @discardableResult public func * (left: SteviaAttribute, right: Double) -> SteviaAttribute { - return SteviaAttribute(view: left.view, attribute: left.attribute, constant: left.constant, multiplier: right) + SteviaAttribute(view: left.view, attribute: left.attribute, constant: left.constant, multiplier: right) +} + +@discardableResult +public func * (left: SteviaAttribute, right: Int) -> SteviaAttribute { + left * Double(right) } @discardableResult public func / (left: SteviaAttribute, right: Double) -> SteviaAttribute { - return left * (1/right) + left * (1/right) +} + +@discardableResult +public func / (left: SteviaAttribute, right: Int) -> SteviaAttribute { + left / Double(right) } @discardableResult public func % (left: Double, right: SteviaAttribute) -> SteviaAttribute { - return right * (left/100) + right * (left/100) +} + +@discardableResult +public func % (left: Int, right: SteviaAttribute) -> SteviaAttribute { + Double(left) % right } // MARK: - Equations of type v.P == X diff --git a/Sources/Stevia/Stevia+Fill.swift b/Sources/Stevia/Stevia+Fill.swift index e54b9a27..cdfc758c 100644 --- a/Sources/Stevia/Stevia+Fill.swift +++ b/Sources/Stevia/Stevia+Fill.swift @@ -11,24 +11,53 @@ import UIKit public extension UIView { + @discardableResult + func fillContainer() -> Self { + fillHorizontally() + fillVertically() + return self + } + + @available(*, deprecated, renamed: "fillContainer(padding:)") + @discardableResult + func fillContainer(_ padding: Double) -> Self { + fillContainer(padding: padding) + } + /** Adds the constraints needed for the view to fill its `superview`. A padding can be used to apply equal spaces between the view and its superview */ @discardableResult - func fillContainer(_ padding: Double = 0) -> Self { - fillHorizontally(m: padding) - fillVertically(m: padding) + func fillContainer(padding: Double) -> Self { + fillHorizontally(padding: padding) + fillVertically(padding: padding) return self } - @available(*, deprecated, message: "Use 'fillVertically' instead") + /** + Adds the constraints needed for the view to fill its `superview`. + A padding can be used to apply equal spaces between the view and its superview + */ + @discardableResult + func fillContainer(padding: Int) -> Self { + fillContainer(padding: Double(padding)) + } + + + @available(*, deprecated, renamed: "fillVertically(padding:)") + @discardableResult + func fillVertically(m points: Double) -> Self { + fill(.vertical, points: points) + } + /** Adds the constraints needed for the view to fill its `superview` Vertically. A padding can be used to apply equal spaces between the view and its superview */ - func fillV(m points: Double = 0) -> Self { - return fill(.vertical, points: points) + @discardableResult + func fillVertically(padding: Double = 0) -> Self { + fill(.vertical, points: padding) } /** @@ -36,17 +65,24 @@ public extension UIView { A padding can be used to apply equal spaces between the view and its superview */ @discardableResult - func fillVertically(m points: Double = 0) -> Self { - return fill(.vertical, points: points) + func fillVertically(padding: Int) -> Self { + fillVertically(padding: Double(padding)) + } + + + @available(*, deprecated, renamed: "fillHorizontally(padding:)") + @discardableResult + func fillHorizontally(m points: Double) -> Self { + fill(.horizontal, points: points) } - @available(*, deprecated, message: "Use 'fillHorizontally' instead") /** Adds the constraints needed for the view to fill its `superview` Horizontally. A padding can be used to apply equal spaces between the view and its superview */ - func fillH(m points: Double = 0) -> Self { - return fill(.horizontal, points: points) + @discardableResult + func fillHorizontally(padding: Double = 0) -> Self { + fill(.horizontal, points: padding) } /** @@ -54,8 +90,8 @@ public extension UIView { A padding can be used to apply equal spaces between the view and its superview */ @discardableResult - func fillHorizontally(m points: Double = 0) -> Self { - return fill(.horizontal, points: points) + func fillHorizontally(padding: Int) -> Self { + fillHorizontally(padding: Double(padding)) } fileprivate func fill(_ axis: NSLayoutConstraint.Axis, points: Double = 0) -> Self { diff --git a/Sources/Stevia/Stevia+Position.swift b/Sources/Stevia/Stevia+Position.swift index c7c8df83..1414da2b 100644 --- a/Sources/Stevia/Stevia+Position.swift +++ b/Sources/Stevia/Stevia+Position.swift @@ -24,7 +24,12 @@ public extension UIView { */ @discardableResult func left(_ points: Double) -> Self { - return position(.left, points: points) + position(.left, points: points) + } + + @discardableResult + func left(_ points: Int) -> Self { + left(Double(points)) } /** Sets the right margin for a view. @@ -43,6 +48,11 @@ public extension UIView { return position(.right, points: -points) } + @discardableResult + func right(_ points: Int) -> Self { + right(Double(points)) + } + /** Sets the top margin for a view. Example Usage : @@ -59,6 +69,11 @@ public extension UIView { return position(.top, points: points) } + @discardableResult + func top(_ points: Int) -> Self { + top(Double(points)) + } + /** Sets the bottom margin for a view. Example Usage : @@ -74,6 +89,11 @@ public extension UIView { func bottom(_ points: Double) -> Self { return position(.bottom, points: -points) } + + @discardableResult + func bottom(_ points: Int) -> Self { + bottom(Double(points)) + } /** Sets the left margin for a view. diff --git a/Sources/Stevia/Stevia+Size.swift b/Sources/Stevia/Stevia+Size.swift index f316c3d9..a37eb4fb 100644 --- a/Sources/Stevia/Stevia+Size.swift +++ b/Sources/Stevia/Stevia+Size.swift @@ -115,8 +115,8 @@ public extension UIView { */ @discardableResult - func width(_ points: Double) -> Self { - size(.width, points: points) + func width(_ points: T) -> Self { + size(.width, points: Double(points)) } /** @@ -133,10 +133,10 @@ public extension UIView { */ @discardableResult - func width(_ points: Int) -> Self { - size(.width, points: Double(points)) + func width(_ points: T) -> Self { + width(Double(points)) } - + /** Adds an Autolayout constraint for setting the view's height. diff --git a/Tests/SteviaTests/CenterTests.swift b/Tests/SteviaTests/CenterTests.swift index 212c975d..9f673132 100644 --- a/Tests/SteviaTests/CenterTests.swift +++ b/Tests/SteviaTests/CenterTests.swift @@ -23,7 +23,19 @@ class CenterTests: XCTestCase { win.rootViewController = ctrler v = UIView() ctrler.view.Subviews { v } - verifyViewHasDefaultValues() + + // verify view h as default values + XCTAssertEqual(v.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.width, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.height, 0, accuracy: CGFloat(Float.ulpOfOne)) + + v.size(100) + ctrler.view.layoutIfNeeded() + XCTAssertEqual(v.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.width, 100, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.height, 100, accuracy: CGFloat(Float.ulpOfOne)) } override func tearDown() { @@ -31,12 +43,6 @@ class CenterTests: XCTestCase { } func testCenterHorizontally() { - v.size(100) - ctrler.view.layoutIfNeeded() - XCTAssertEqual(v.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) - XCTAssertEqual(v.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) - XCTAssertEqual(v.frame.width, 100, accuracy: CGFloat(Float.ulpOfOne)) - XCTAssertEqual(v.frame.height, 100, accuracy: CGFloat(Float.ulpOfOne)) v.centerHorizontally() ctrler.view.setNeedsLayout() ctrler.view.layoutIfNeeded() @@ -48,14 +54,20 @@ class CenterTests: XCTestCase { XCTAssertEqual(v.frame.height, 100, accuracy: CGFloat(Float.ulpOfOne)) } - func testCenterHorizontallyWithOffset() { - v.size(100) + func testCenterHorizontallyWithOffsetDouble() { + v.centerHorizontally(offset: Double(50)) + ctrler.view.setNeedsLayout() ctrler.view.layoutIfNeeded() XCTAssertEqual(v.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) - XCTAssertEqual(v.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.origin.x - 50, + ctrler.view.frame.width/2.0 - (v.frame.width/2.0), + accuracy: CGFloat(magicalIphoneXShift)) XCTAssertEqual(v.frame.width, 100, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(v.frame.height, 100, accuracy: CGFloat(Float.ulpOfOne)) - v.centerHorizontally(50) + } + + func testCenterHorizontallyWithOffsetCGFloat() { + v.centerHorizontally(offset: CGFloat(50)) ctrler.view.setNeedsLayout() ctrler.view.layoutIfNeeded() XCTAssertEqual(v.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) @@ -65,15 +77,20 @@ class CenterTests: XCTestCase { XCTAssertEqual(v.frame.width, 100, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(v.frame.height, 100, accuracy: CGFloat(Float.ulpOfOne)) } - - func testCenterVertically() { - v.size(100) + func testCenterHorizontallyWithOffsetInt() { + v.centerHorizontally(offset: Int(50)) + ctrler.view.setNeedsLayout() ctrler.view.layoutIfNeeded() XCTAssertEqual(v.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) - XCTAssertEqual(v.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.origin.x - 50, + ctrler.view.frame.width/2.0 - (v.frame.width/2.0), + accuracy: CGFloat(magicalIphoneXShift)) XCTAssertEqual(v.frame.width, 100, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(v.frame.height, 100, accuracy: CGFloat(Float.ulpOfOne)) + } + + func testCenterVertically() { v.centerVertically() ctrler.view.setNeedsLayout() ctrler.view.layoutIfNeeded() @@ -85,14 +102,20 @@ class CenterTests: XCTestCase { XCTAssertEqual(v.frame.height, 100, accuracy: CGFloat(Float.ulpOfOne)) } - func testCenterVerticallyWithOffset() { - v.size(100) + func testCenterVerticallyWithOffsetDouble() { + v.centerVertically(offset: Double(50)) + ctrler.view.setNeedsLayout() ctrler.view.layoutIfNeeded() - XCTAssertEqual(v.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.origin.y - 50, + ctrler.view.frame.height/2.0 - (v.frame.height/2.0), + accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(v.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(v.frame.width, 100, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(v.frame.height, 100, accuracy: CGFloat(Float.ulpOfOne)) - v.centerVertically(50) + } + + func testCenterVerticallyWithOffsetCGFloat() { + v.centerVertically(offset: CGFloat(50)) ctrler.view.setNeedsLayout() ctrler.view.layoutIfNeeded() XCTAssertEqual(v.frame.origin.y - 50, @@ -103,13 +126,19 @@ class CenterTests: XCTestCase { XCTAssertEqual(v.frame.height, 100, accuracy: CGFloat(Float.ulpOfOne)) } - func testCenterInContainer() { - v.size(100) + func testCenterVerticallyWithOffsetInt() { + v.centerVertically(offset: Int(50)) + ctrler.view.setNeedsLayout() ctrler.view.layoutIfNeeded() - XCTAssertEqual(v.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.origin.y - 50, + ctrler.view.frame.height/2.0 - (v.frame.height/2.0), + accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(v.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(v.frame.width, 100, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(v.frame.height, 100, accuracy: CGFloat(Float.ulpOfOne)) + } + + func testCenterInContainer() { v.centerInContainer() ctrler.view.setNeedsLayout() ctrler.view.layoutIfNeeded() @@ -122,11 +151,4 @@ class CenterTests: XCTestCase { XCTAssertEqual(v.frame.width, 100, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(v.frame.height, 100, accuracy: CGFloat(Float.ulpOfOne)) } - - func verifyViewHasDefaultValues() { - XCTAssertEqual(v.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) - XCTAssertEqual(v.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) - XCTAssertEqual(v.frame.width, 0, accuracy: CGFloat(Float.ulpOfOne)) - XCTAssertEqual(v.frame.height, 0, accuracy: CGFloat(Float.ulpOfOne)) - } } diff --git a/Tests/SteviaTests/EquationTests.swift b/Tests/SteviaTests/EquationTests.swift index 159770f9..327de90e 100644 --- a/Tests/SteviaTests/EquationTests.swift +++ b/Tests/SteviaTests/EquationTests.swift @@ -406,7 +406,7 @@ class EquationTests: XCTestCase { dropdown } - box.fillContainer(60) + box.fillContainer(padding: 60) |-field-|.top(1).height(50)//centerVertically() |dropdown| diff --git a/Tests/SteviaTests/FillTests.swift b/Tests/SteviaTests/FillTests.swift index 3ad2c946..4c16a718 100644 --- a/Tests/SteviaTests/FillTests.swift +++ b/Tests/SteviaTests/FillTests.swift @@ -38,7 +38,7 @@ class FillTests: XCTestCase { let padding = 10.0 let b = UIButton() ctrler.view.Subviews { b } - b.fillContainer(padding) + b.fillContainer(padding: padding) ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(ctrler.view.frame.height, b.frame.height + CGFloat(padding) * 2, accuracy: CGFloat(Float.ulpOfOne)) diff --git a/Tests/SteviaTests/SizeTests.swift b/Tests/SteviaTests/SizeTests.swift index 72a56edd..62d020c1 100644 --- a/Tests/SteviaTests/SizeTests.swift +++ b/Tests/SteviaTests/SizeTests.swift @@ -32,6 +32,15 @@ class SizeTests: XCTestCase { func testSize() { v.size(57) + +// v.width(1) +// v.width(1.0) +// v.width(CGFloat(1)) +// v.width(Float(1)) +// v.width(Double(1)) +// v.width(Int(1)) +// v.width(UInt(1)) + ctrler.view.layoutIfNeeded() XCTAssertEqual(v.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(v.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) From 2b7b6924bdf3b597a46a68545872a7140e8e8f1e Mon Sep 17 00:00:00 2001 From: S4cha Date: Thu, 2 Apr 2020 10:54:39 +0200 Subject: [PATCH 04/12] WIP - BinaryFloatingPoint/Integer --- Sources/Stevia/Stevia+Equation.swift | 60 ++++++++---- Sources/Stevia/Stevia+Fill.swift | 42 ++++---- Sources/Stevia/Stevia+FlexibleMargin.swift | 17 ++-- Tests/SteviaTests/EquationTests.swift | 102 +++++++++++++++++--- Tests/SteviaTests/FillTests.swift | 97 ++++++++++++++++++- Tests/SteviaTests/FlexibleMarginTests.swift | 44 ++++++++- 6 files changed, 294 insertions(+), 68 deletions(-) diff --git a/Sources/Stevia/Stevia+Equation.swift b/Sources/Stevia/Stevia+Equation.swift index 770c23e7..cbe9096e 100644 --- a/Sources/Stevia/Stevia+Equation.swift +++ b/Sources/Stevia/Stevia+Equation.swift @@ -183,28 +183,33 @@ private func applyRelation(left: SteviaAttribute, right: SteviaAttribute, relate } @discardableResult -public func + (left: SteviaAttribute, right: Double) -> SteviaAttribute { - SteviaAttribute(view: left.view, attribute: left.attribute, constant: right, multiplier: left.multiplier) +public func + (left: SteviaAttribute, right: T) -> SteviaAttribute { + SteviaAttribute(view: left.view, attribute: left.attribute, constant: Double(right), multiplier: left.multiplier) } @discardableResult -public func + (left: SteviaAttribute, right: Int) -> SteviaAttribute { +public func + (left: SteviaAttribute, right: T) -> SteviaAttribute { left + Double(right) } @discardableResult -public func - (left: SteviaAttribute, right: Double) -> SteviaAttribute { - SteviaAttribute(view: left.view, attribute: left.attribute, constant: -right, multiplier: left.multiplier) +public func - (left: SteviaAttribute, right: T) -> SteviaAttribute { + SteviaAttribute(view: left.view, attribute: left.attribute, constant: -Double(right), multiplier: left.multiplier) } @discardableResult -public func - (left: SteviaAttribute, right: Int) -> SteviaAttribute { +public func - (left: SteviaAttribute, right: T) -> SteviaAttribute { left - Double(right) } @discardableResult -public func * (left: SteviaAttribute, right: Double) -> SteviaAttribute { - SteviaAttribute(view: left.view, attribute: left.attribute, constant: left.constant, multiplier: right) +public func * (left: SteviaAttribute, right: T) -> SteviaAttribute { + SteviaAttribute(view: left.view, attribute: left.attribute, constant: left.constant, multiplier: Double(right)) +} + +@discardableResult +public func * (left: SteviaAttribute, right: T) -> SteviaAttribute { + left * Double(right) } @discardableResult @@ -213,29 +218,29 @@ public func * (left: SteviaAttribute, right: Int) -> SteviaAttribute { } @discardableResult -public func / (left: SteviaAttribute, right: Double) -> SteviaAttribute { - left * (1/right) +public func / (left: SteviaAttribute, right: T) -> SteviaAttribute { + left * (1/Double(right)) } @discardableResult -public func / (left: SteviaAttribute, right: Int) -> SteviaAttribute { +public func / (left: SteviaAttribute, right: T) -> SteviaAttribute { left / Double(right) } @discardableResult -public func % (left: Double, right: SteviaAttribute) -> SteviaAttribute { - right * (left/100) +public func % (left: T, right: SteviaAttribute) -> SteviaAttribute { + right * (Double(left)/100) } @discardableResult -public func % (left: Int, right: SteviaAttribute) -> SteviaAttribute { +public func % (left: T, right: SteviaAttribute) -> SteviaAttribute { Double(left) % right } // MARK: - Equations of type v.P == X @discardableResult -public func == (left: SteviaAttribute, right: Double) -> NSLayoutConstraint { +public func == (left: SteviaAttribute, right: T) -> NSLayoutConstraint { if let spv = left.view.superview { var toItem: UIView? = spv var constant = right @@ -248,13 +253,18 @@ public func == (left: SteviaAttribute, right: Double) -> NSLayoutConstraint { return spv.addConstraint(item: left.view, attribute: left.attribute, toItem: toItem, - constant: constant) + constant: Double(constant)) } return NSLayoutConstraint() } @discardableResult -public func >= (left: SteviaAttribute, right: Double) -> NSLayoutConstraint { +public func == (left: SteviaAttribute, right: T) -> NSLayoutConstraint { + left == Double(right) +} + +@discardableResult +public func >= (left: SteviaAttribute, right: T) -> NSLayoutConstraint { if let spv = left.view.superview { var toItem: UIView? = spv var constant = right @@ -268,13 +278,18 @@ public func >= (left: SteviaAttribute, right: Double) -> NSLayoutConstraint { attribute: left.attribute, relatedBy: .greaterThanOrEqual, toItem: toItem, - constant: constant) + constant: Double(constant)) } return NSLayoutConstraint() } @discardableResult -public func <= (left: SteviaAttribute, right: Double) -> NSLayoutConstraint { +public func >= (left: SteviaAttribute, right: T) -> NSLayoutConstraint { + left >= Double(right) +} + +@discardableResult +public func <= (left: SteviaAttribute, right: T) -> NSLayoutConstraint { if let spv = left.view.superview { var toItem: UIView? = spv var constant = right @@ -288,8 +303,13 @@ public func <= (left: SteviaAttribute, right: Double) -> NSLayoutConstraint { attribute: left.attribute, relatedBy: .lessThanOrEqual, toItem: toItem, - constant: constant) + constant: Double(constant)) } return NSLayoutConstraint() } + +@discardableResult +public func <= (left: SteviaAttribute, right: T) -> NSLayoutConstraint { + left <= Double(right) +} #endif diff --git a/Sources/Stevia/Stevia+Fill.swift b/Sources/Stevia/Stevia+Fill.swift index cdfc758c..4ebcd2ff 100644 --- a/Sources/Stevia/Stevia+Fill.swift +++ b/Sources/Stevia/Stevia+Fill.swift @@ -18,18 +18,12 @@ public extension UIView { return self } - @available(*, deprecated, renamed: "fillContainer(padding:)") - @discardableResult - func fillContainer(_ padding: Double) -> Self { - fillContainer(padding: padding) - } - /** Adds the constraints needed for the view to fill its `superview`. A padding can be used to apply equal spaces between the view and its superview */ @discardableResult - func fillContainer(padding: Double) -> Self { + func fillContainer(padding: T) -> Self { fillHorizontally(padding: padding) fillVertically(padding: padding) return self @@ -44,11 +38,13 @@ public extension UIView { fillContainer(padding: Double(padding)) } - - @available(*, deprecated, renamed: "fillVertically(padding:)") + /** + Adds the constraints needed for the view to fill its `superview` Vertically. + A padding can be used to apply equal spaces between the view and its superview + */ @discardableResult - func fillVertically(m points: Double) -> Self { - fill(.vertical, points: points) + func fillVertically() -> Self { + fill(.vertical) } /** @@ -56,8 +52,8 @@ public extension UIView { A padding can be used to apply equal spaces between the view and its superview */ @discardableResult - func fillVertically(padding: Double = 0) -> Self { - fill(.vertical, points: padding) + func fillVertically(padding: T) -> Self { + fill(.vertical, points: Double(padding)) } /** @@ -65,24 +61,26 @@ public extension UIView { A padding can be used to apply equal spaces between the view and its superview */ @discardableResult - func fillVertically(padding: Int) -> Self { + func fillVertically(padding: T) -> Self { fillVertically(padding: Double(padding)) } - - @available(*, deprecated, renamed: "fillHorizontally(padding:)") + /** + Adds the constraints needed for the view to fill its `superview` Horizontally. + A padding can be used to apply equal spaces between the view and its superview + */ @discardableResult - func fillHorizontally(m points: Double) -> Self { - fill(.horizontal, points: points) + func fillHorizontally() -> Self { + fill(.horizontal) } - + /** Adds the constraints needed for the view to fill its `superview` Horizontally. A padding can be used to apply equal spaces between the view and its superview */ @discardableResult - func fillHorizontally(padding: Double = 0) -> Self { - fill(.horizontal, points: padding) + func fillHorizontally(padding: T) -> Self { + fill(.horizontal, points: Double(padding)) } /** @@ -90,7 +88,7 @@ public extension UIView { A padding can be used to apply equal spaces between the view and its superview */ @discardableResult - func fillHorizontally(padding: Int) -> Self { + func fillHorizontally(padding: T) -> Self { fillHorizontally(padding: Double(padding)) } diff --git a/Sources/Stevia/Stevia+FlexibleMargin.swift b/Sources/Stevia/Stevia+FlexibleMargin.swift index d3f23c65..5b9ebd65 100644 --- a/Sources/Stevia/Stevia+FlexibleMargin.swift +++ b/Sources/Stevia/Stevia+FlexibleMargin.swift @@ -11,25 +11,24 @@ import UIKit prefix operator >= @discardableResult -public prefix func >= (p: Double) -> SteviaFlexibleMargin { - SteviaFlexibleMargin(points: p, relation: .greaterThanOrEqual) +public prefix func >= (p: T) -> SteviaFlexibleMargin { + SteviaFlexibleMargin(points: Double(p), relation: .greaterThanOrEqual) } @discardableResult -public prefix func >= (p: Int) -> SteviaFlexibleMargin { - SteviaFlexibleMargin(points: Double(p), relation: .greaterThanOrEqual) +public prefix func >= (p: T) -> SteviaFlexibleMargin { + >=Double(p) } - prefix operator <= @discardableResult -public prefix func <= (p: Double) -> SteviaFlexibleMargin { - SteviaFlexibleMargin(points: p, relation: .lessThanOrEqual) +public prefix func <= (p: T) -> SteviaFlexibleMargin { + SteviaFlexibleMargin(points: Double(p), relation: .lessThanOrEqual) } @discardableResult -public prefix func <= (p: Int) -> SteviaFlexibleMargin { - SteviaFlexibleMargin(points: Double(p), relation: .lessThanOrEqual) +public prefix func <= (p: T) -> SteviaFlexibleMargin { + <=Double(p) } public struct SteviaFlexibleMargin { diff --git a/Tests/SteviaTests/EquationTests.swift b/Tests/SteviaTests/EquationTests.swift index 327de90e..991c411a 100644 --- a/Tests/SteviaTests/EquationTests.swift +++ b/Tests/SteviaTests/EquationTests.swift @@ -25,10 +25,26 @@ class EquationTests: XCTestCase { super.tearDown() } - func testTop() { + func testTopDouble() { let v = UIView() ctrler.view.Subviews { v } - v.Top == ctrler.view.Top + 10 + v.Top == ctrler.view.Top + Double(10) + ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in + XCTAssertEqual(v.frame.origin.y, 10) + } + + func testTopCGFloat() { + let v = UIView() + ctrler.view.Subviews { v } + v.Top == ctrler.view.Top + CGFloat(10) + ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in + XCTAssertEqual(v.frame.origin.y, 10) + } + + func testTopInt() { + let v = UIView() + ctrler.view.Subviews { v } + v.Top == ctrler.view.Top + Int(10) ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, 10) } @@ -57,10 +73,26 @@ class EquationTests: XCTestCase { XCTAssertEqual(v.frame.origin.y, 10) } - func testBottom() { + func testBottomDouble() { let v = UIView() ctrler.view.Subviews { v } - v.Bottom == ctrler.view.Bottom - 23 + v.Bottom == ctrler.view.Bottom - Double(23) + ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in + XCTAssertEqual(v.frame.origin.y, ctrler.view.frame.height - 23) + } + + func testBottomCGFloat() { + let v = UIView() + ctrler.view.Subviews { v } + v.Bottom == ctrler.view.Bottom - CGFloat(23) + ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in + XCTAssertEqual(v.frame.origin.y, ctrler.view.frame.height - 23) + } + + func testBottomInt() { + let v = UIView() + ctrler.view.Subviews { v } + v.Bottom == ctrler.view.Bottom - Int(23) ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, ctrler.view.frame.height - 23) } @@ -219,26 +251,74 @@ class EquationTests: XCTestCase { // Single Value - func testSingleValueTop() { + func testSingleValueTopDouble() { let v = UIView() ctrler.view.Subviews { v } - v.Top == 10 + v.Top == Double(10) ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, 10) } - func testSingleValueTopGreaterOrEqual() { + func testSingleValueTopCGFloat() { let v = UIView() ctrler.view.Subviews { v } - v.Top >= 10 + v.Top == CGFloat(10) ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, 10) } - func testSingleValueLessOrEqual() { + func testSingleValueTopInt() { let v = UIView() ctrler.view.Subviews { v } - v.Top <= 10 + v.Top == Int(10) + ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in + XCTAssertEqual(v.frame.origin.y, 10) + } + + func testSingleValueTopGreaterOrEqualDouble() { + let v = UIView() + ctrler.view.Subviews { v } + v.Top >= Double(10) + ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in + XCTAssertEqual(v.frame.origin.y, 10) + } + + func testSingleValueTopGreaterOrEqualCGFloat() { + let v = UIView() + ctrler.view.Subviews { v } + v.Top >= CGFloat(10) + ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in + XCTAssertEqual(v.frame.origin.y, 10) + } + + func testSingleValueTopGreaterOrEqualInt() { + let v = UIView() + ctrler.view.Subviews { v } + v.Top >= Int(10) + ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in + XCTAssertEqual(v.frame.origin.y, 10) + } + + func testSingleValueLessOrEqualDouble() { + let v = UIView() + ctrler.view.Subviews { v } + v.Top <= Double(10) + ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in + XCTAssertEqual(v.frame.origin.y, 10) + } + + func testSingleValueLessOrEqualCGFloat() { + let v = UIView() + ctrler.view.Subviews { v } + v.Top <= CGFloat(10) + ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in + XCTAssertEqual(v.frame.origin.y, 10) + } + + func testSingleValueLessOrEqualInt() { + let v = UIView() + ctrler.view.Subviews { v } + v.Top <= Int(10) ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, 10) } @@ -434,7 +514,7 @@ class EquationTests: XCTestCase { dropdown } - box.fillContainer(60) + box.fillContainer(padding: 60) |-field-|.top(1).height(50)//centerVertically() |dropdown| diff --git a/Tests/SteviaTests/FillTests.swift b/Tests/SteviaTests/FillTests.swift index 4c16a718..55227c25 100644 --- a/Tests/SteviaTests/FillTests.swift +++ b/Tests/SteviaTests/FillTests.swift @@ -33,9 +33,20 @@ class FillTests: XCTestCase { XCTAssertEqual(ctrler.view.frame, b.frame) } + func testFillContainerWithPaddingDouble() { + let padding: Double = 10.0 + let b = UIButton() + ctrler.view.Subviews { b } + b.fillContainer(padding: padding) + ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in + XCTAssertEqual(ctrler.view.frame.height, b.frame.height + CGFloat(padding) * 2, + accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(ctrler.view.frame.width, b.frame.width + CGFloat(padding) * 2, + accuracy: CGFloat(Float.ulpOfOne)) + } - func testFillContainerWithPadding() { - let padding = 10.0 + func testFillContainerWithPaddingCGFloat() { + let padding: CGFloat = 10.0 let b = UIButton() ctrler.view.Subviews { b } b.fillContainer(padding: padding) @@ -45,4 +56,86 @@ class FillTests: XCTestCase { XCTAssertEqual(ctrler.view.frame.width, b.frame.width + CGFloat(padding) * 2, accuracy: CGFloat(Float.ulpOfOne)) } + + func testFillContainerWithPaddingInt() { + let padding: Int = 10 + let b = UIButton() + ctrler.view.Subviews { b } + b.fillContainer(padding: padding) + ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in + XCTAssertEqual(ctrler.view.frame.height, b.frame.height + CGFloat(padding) * 2, + accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(ctrler.view.frame.width, b.frame.width + CGFloat(padding) * 2, + accuracy: CGFloat(Float.ulpOfOne)) + } + + func testFillVertically() { + let b = UIButton() + ctrler.view.Subviews { b } + b.width(10) + b.fillVertically() + ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in + XCTAssertEqual(ctrler.view.frame.height, b.frame.height) + XCTAssertEqual(10, b.frame.width) + } + + func testFillVerticallyWithPaddingDouble() { + let padding: Double = 40.0 + let b = UIButton() + ctrler.view.Subviews { b } + b.fillVertically(padding: padding) + ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in + XCTAssertEqual(ctrler.view.frame.height, b.frame.height + CGFloat(padding) * 2, + accuracy: CGFloat(Float.ulpOfOne)) + } + + func testFillVerticallyWithPaddingCGFloat() { + let padding: CGFloat = 30.0 + let b = UIButton() + ctrler.view.Subviews { b } + b.fillVertically(padding: padding) + ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in + XCTAssertEqual(ctrler.view.frame.height, b.frame.height + CGFloat(padding) * 2, + accuracy: CGFloat(Float.ulpOfOne)) + } + + func testFillVerticallyWithPaddingInt() { + let padding: Int = 14 + let b = UIButton() + ctrler.view.Subviews { b } + b.fillVertically(padding: padding) + ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in + XCTAssertEqual(ctrler.view.frame.height, b.frame.height + CGFloat(padding) * 2, + accuracy: CGFloat(Float.ulpOfOne)) + } + + func testFillHorizontallyWithPaddingDouble() { + let padding: Double = 40.0 + let b = UIButton() + ctrler.view.Subviews { b } + b.fillHorizontally(padding: padding) + ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in + XCTAssertEqual(ctrler.view.frame.width, b.frame.width + CGFloat(padding) * 2, + accuracy: CGFloat(Float.ulpOfOne)) + } + + func testFillHorizontallyWithPaddingCGFloat() { + let padding: CGFloat = 30.0 + let b = UIButton() + ctrler.view.Subviews { b } + b.fillHorizontally(padding: padding) + ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in + XCTAssertEqual(ctrler.view.frame.width, b.frame.width + CGFloat(padding) * 2, + accuracy: CGFloat(Float.ulpOfOne)) + } + + func testFillHorizontallyWithPaddingInt() { + let padding: Int = 14 + let b = UIButton() + ctrler.view.Subviews { b } + b.fillHorizontally(padding: padding) + ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in + XCTAssertEqual(ctrler.view.frame.width, b.frame.width + CGFloat(padding) * 2, + accuracy: CGFloat(Float.ulpOfOne)) + } } diff --git a/Tests/SteviaTests/FlexibleMarginTests.swift b/Tests/SteviaTests/FlexibleMarginTests.swift index 1c36f60a..97bd04db 100644 --- a/Tests/SteviaTests/FlexibleMarginTests.swift +++ b/Tests/SteviaTests/FlexibleMarginTests.swift @@ -31,8 +31,26 @@ class FlexibleMarginTests: XCTestCase { /// Todo stress test by pushing views - func testGreaterTop() { - v.top(>=23) + func testGreaterTopDouble() { + v.top(>=Double(23)) + ctrler.view.layoutIfNeeded() + XCTAssertEqual(v.frame.origin.y, 23, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.width, 100, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.height, 100, accuracy: CGFloat(Float.ulpOfOne)) + } + + func testGreaterTopCGFloat() { + v.top(>=CGFloat(23)) + ctrler.view.layoutIfNeeded() + XCTAssertEqual(v.frame.origin.y, 23, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.width, 100, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.height, 100, accuracy: CGFloat(Float.ulpOfOne)) + } + + func testGreaterTopInt() { + v.top(>=Int(23)) ctrler.view.layoutIfNeeded() XCTAssertEqual(v.frame.origin.y, 23, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(v.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) @@ -108,8 +126,26 @@ class FlexibleMarginTests: XCTestCase { XCTAssertEqual(v.frame.height, 100, accuracy: CGFloat(Float.ulpOfOne)) } - func testLessTop() { - v.top(<=23) + func testLessTopDouble() { + v.top(<=Double(23)) + ctrler.view.layoutIfNeeded() + XCTAssertEqual(v.frame.origin.y, 23, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.width, 100, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.height, 100, accuracy: CGFloat(Float.ulpOfOne)) + } + + func testLessTopCGFloat() { + v.top(<=CGFloat(23)) + ctrler.view.layoutIfNeeded() + XCTAssertEqual(v.frame.origin.y, 23, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.width, 100, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.height, 100, accuracy: CGFloat(Float.ulpOfOne)) + } + + func testLessTopInt() { + v.top(<=Int(23)) ctrler.view.layoutIfNeeded() XCTAssertEqual(v.frame.origin.y, 23, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(v.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) From f09213a4cbb3746ddbac46b3929d5903b9f25c5d Mon Sep 17 00:00:00 2001 From: S4cha Date: Thu, 2 Apr 2020 12:35:23 +0200 Subject: [PATCH 05/12] Finishes BinaryFloatingPoint/Integer + Tests --- Sources/Stevia/Stevia+Equation.swift | 5 - Sources/Stevia/Stevia+Fill.swift | 2 +- Sources/Stevia/Stevia+Operators.swift | 57 ++--- Sources/Stevia/Stevia+Percentage.swift | 8 +- Sources/Stevia/Stevia+Position.swift | 114 +++++++-- Sources/Stevia/Stevia+Size.swift | 12 +- Sources/Stevia/Stevia+Stacks.swift | 13 +- Tests/SteviaTests/FullLayoutTests.swift | 8 +- Tests/SteviaTests/LayoutTests.swift | 297 ++++++++++++++++++++++-- Tests/SteviaTests/PositionTests.swift | 138 ++++++++++- Tests/SteviaTests/SizeTests.swift | 57 +++-- Tests/SteviaTests/SteviaTests.swift | 14 -- 12 files changed, 597 insertions(+), 128 deletions(-) delete mode 100644 Tests/SteviaTests/SteviaTests.swift diff --git a/Sources/Stevia/Stevia+Equation.swift b/Sources/Stevia/Stevia+Equation.swift index cbe9096e..3591af6f 100644 --- a/Sources/Stevia/Stevia+Equation.swift +++ b/Sources/Stevia/Stevia+Equation.swift @@ -212,11 +212,6 @@ public func * (left: SteviaAttribute, right: T) -> SteviaAttri left * Double(right) } -@discardableResult -public func * (left: SteviaAttribute, right: Int) -> SteviaAttribute { - left * Double(right) -} - @discardableResult public func / (left: SteviaAttribute, right: T) -> SteviaAttribute { left * (1/Double(right)) diff --git a/Sources/Stevia/Stevia+Fill.swift b/Sources/Stevia/Stevia+Fill.swift index 4ebcd2ff..7694a91c 100644 --- a/Sources/Stevia/Stevia+Fill.swift +++ b/Sources/Stevia/Stevia+Fill.swift @@ -34,7 +34,7 @@ public extension UIView { A padding can be used to apply equal spaces between the view and its superview */ @discardableResult - func fillContainer(padding: Int) -> Self { + func fillContainer(padding: T) -> Self { fillContainer(padding: Double(padding)) } diff --git a/Sources/Stevia/Stevia+Operators.swift b/Sources/Stevia/Stevia+Operators.swift index fb0d4d70..e736e9e0 100644 --- a/Sources/Stevia/Stevia+Operators.swift +++ b/Sources/Stevia/Stevia+Operators.swift @@ -28,15 +28,17 @@ precedencegroup HeightPrecedence { } @discardableResult -public func ~ (left: UIView, right: Double) -> UIView { +public func ~ (left: UIView, right: T) -> UIView { left.height(right) } @discardableResult -public func ~ (left: UIView, right: Int) -> UIView { - left.height(right) +public func ~ (left: UIView, right: T) -> UIView { + left ~ Double(right) } + + @discardableResult public func ~ (left: UIView, right: SteviaPercentage) -> UIView { left.height(right) @@ -48,15 +50,14 @@ public func ~ (left: UIView, right: SteviaFlexibleMargin) -> UIView { } @discardableResult -public func ~ (left: [UIView], right: Double) -> [UIView] { +public func ~ (left: [UIView], right: T) -> [UIView] { for l in left { l.height(right) } return left } @discardableResult -public func ~ (left: [UIView], right: Int) -> [UIView] { - for l in left { l.height(right) } - return left +public func ~ (left: [UIView], right: T) -> [UIView] { + left ~ Double(right) } @discardableResult @@ -67,17 +68,15 @@ public func ~ (left: [UIView], right: SteviaFlexibleMargin) -> [UIView] { prefix operator |- @discardableResult -public prefix func |- (p: Double) -> SideConstraint { +public prefix func |- (p: T) -> SideConstraint { var s = SideConstraint() - s.constant = p + s.constant = Double(p) return s } @discardableResult -public prefix func |- (p: Int) -> SideConstraint { - var s = SideConstraint() - s.constant = Double(p) - return s +public prefix func |- (p: T) -> SideConstraint { + |-Double(p) } @discardableResult @@ -87,17 +86,15 @@ public prefix func |- (v: UIView) -> UIView { postfix operator -| @discardableResult -public postfix func -| (p: Double) -> SideConstraint { +public postfix func -| (p: T) -> SideConstraint { var s = SideConstraint() - s.constant = p + s.constant = Double(p) return s } @discardableResult -public postfix func -| (p: Int) -> SideConstraint { - var s = SideConstraint() - s.constant = Double(p) - return s +public postfix func -| (p: T) -> SideConstraint { + Double(p)-| } @discardableResult @@ -116,19 +113,16 @@ public struct PartialConstraint { } @discardableResult -public func - (left: UIView, right: Double) -> PartialConstraint { +public func - (left: UIView, right: T) -> PartialConstraint { var p = PartialConstraint() p.view1 = left - p.constant = right + p.constant = Double(right) return p } @discardableResult -public func - (left: UIView, right: Int) -> PartialConstraint { - var p = PartialConstraint() - p.view1 = left - p.constant = Double(right) - return p +public func - (left: UIView, right: T) -> PartialConstraint { + left-Double(right) } // Side Constraints @@ -203,19 +197,16 @@ public func - (left: UIView, right: UIView) -> [UIView] { } @discardableResult -public func - (left: [UIView], right: Double) -> PartialConstraint { +public func - (left: [UIView], right: T) -> PartialConstraint { var p = PartialConstraint() - p.constant = right + p.constant = Double(right) p.views = left return p } @discardableResult -public func - (left: [UIView], right: Int) -> PartialConstraint { - var p = PartialConstraint() - p.constant = Double(right) - p.views = left - return p +public func - (left: [UIView], right: T) -> PartialConstraint { + left-Double(right) } @discardableResult diff --git a/Sources/Stevia/Stevia+Percentage.swift b/Sources/Stevia/Stevia+Percentage.swift index 884dfa93..de00fa7c 100644 --- a/Sources/Stevia/Stevia+Percentage.swift +++ b/Sources/Stevia/Stevia+Percentage.swift @@ -14,12 +14,12 @@ public struct SteviaPercentage { } postfix operator % -public postfix func % (v: Double) -> SteviaPercentage { - return SteviaPercentage(value: v) +public postfix func % (v: T) -> SteviaPercentage { + SteviaPercentage(value: Double(v)) } -public postfix func % (v: Int) -> SteviaPercentage { - return SteviaPercentage(value: Double(v)) +public postfix func % (v: T) -> SteviaPercentage { + Double(v)% } public extension UIView { diff --git a/Sources/Stevia/Stevia+Position.swift b/Sources/Stevia/Stevia+Position.swift index 1414da2b..ecc95d60 100644 --- a/Sources/Stevia/Stevia+Position.swift +++ b/Sources/Stevia/Stevia+Position.swift @@ -23,12 +23,23 @@ public extension UIView { - Returns: Itself for chaining purposes */ @discardableResult - func left(_ points: Double) -> Self { - position(.left, points: points) + func left(_ points: T) -> Self { + position(.left, points: Double(points)) } + /** Sets the left margin for a view. + + Example Usage : + + label.left(20) + label.left(<=20) + label.left(>=20) + label.left(20%) + + - Returns: Itself for chaining purposes + */ @discardableResult - func left(_ points: Int) -> Self { + func left(_ points: T) -> Self { left(Double(points)) } @@ -44,12 +55,23 @@ public extension UIView { - Returns: Itself for chaining purposes */ @discardableResult - func right(_ points: Double) -> Self { - return position(.right, points: -points) + func right(_ points: T) -> Self { + position(.right, points: -Double(points)) } + /** Sets the right margin for a view. + + Example Usage : + + label.right(20) + label.right(<=20) + label.right(>=20) + label.right(20%) + + - Returns: Itself for chaining purposes + */ @discardableResult - func right(_ points: Int) -> Self { + func right(_ points: T) -> Self { right(Double(points)) } @@ -65,12 +87,23 @@ public extension UIView { - Returns: Itself for chaining purposes */ @discardableResult - func top(_ points: Double) -> Self { - return position(.top, points: points) + func top(_ points: T) -> Self { + position(.top, points: Double(points)) } + /** Sets the top margin for a view. + + Example Usage : + + label.top(20) + label.top(<=20) + label.top(>=20) + label.top(20%) + + - Returns: Itself for chaining purposes + */ @discardableResult - func top(_ points: Int) -> Self { + func top(_ points: T) -> Self { top(Double(points)) } @@ -86,12 +119,23 @@ public extension UIView { - Returns: Itself for chaining purposes */ @discardableResult - func bottom(_ points: Double) -> Self { - return position(.bottom, points: -points) + func bottom(_ points: T) -> Self { + position(.bottom, points: -Double(points)) } + /** Sets the bottom margin for a view. + + Example Usage : + + label.bottom(20) + label.bottom(<=20) + label.bottom(>=20) + label.bottom(20%) + + - Returns: Itself for chaining purposes + */ @discardableResult - func bottom(_ points: Int) -> Self { + func bottom(_ points: T) -> Self { bottom(Double(points)) } @@ -108,7 +152,7 @@ public extension UIView { */ @discardableResult func left(_ fm: SteviaFlexibleMargin) -> Self { - return position(.left, relatedBy: fm.relation, points: fm.points) + position(.left, relatedBy: fm.relation, points: fm.points) } /** Sets the right margin for a view. @@ -149,7 +193,7 @@ public extension UIView { */ @discardableResult func top(_ fm: SteviaFlexibleMargin) -> Self { - return position(.top, relatedBy: fm.relation, points: fm.points) + position(.top, relatedBy: fm.relation, points: fm.points) } /** Sets the bottom margin for a view. @@ -190,13 +234,45 @@ public extension UIView { */ @discardableResult - func leading(_ points: Double) -> UIView { - return position(.leading, points: points) + func leading(_ points: T) -> UIView { + position(.leading, points: Double(points)) + } + + /** Sets the leading margin for a view. + + Example Usage : + + label.leading(20) + label.leading(<=20) + label.leading(>=20) + label.leading(20%) + + - Returns: itself for chaining purposes + */ + @discardableResult + func leading(_ points: T) -> UIView { + leading(Double(points)) } @discardableResult func leading(_ fm: SteviaFlexibleMargin) -> UIView { - return position(.leading, relatedBy: fm.relation, points: fm.points) + position(.leading, relatedBy: fm.relation, points: fm.points) + } + + /** Sets the trailing margin for a view. + + Example Usage : + + label.trailing(20) + label.trailing(<=20) + label.trailing(>=20) + label.trailing(20%) + + - Returns: itself for chaining purposes + */ + @discardableResult + func trailing(_ points: T) -> UIView { + position(.trailing, points: -Double(points)) } /** Sets the trailing margin for a view. @@ -211,8 +287,8 @@ public extension UIView { - Returns: itself for chaining purposes */ @discardableResult - func trailing(_ points: Double) -> UIView { - return position(.trailing, points: -points) + func trailing(_ points: T) -> UIView { + trailing(Double(points)) } @discardableResult diff --git a/Sources/Stevia/Stevia+Size.swift b/Sources/Stevia/Stevia+Size.swift index a37eb4fb..13889a55 100644 --- a/Sources/Stevia/Stevia+Size.swift +++ b/Sources/Stevia/Stevia+Size.swift @@ -27,7 +27,7 @@ public extension UIView { */ @discardableResult - func size(_ points: Double) -> Self { + func size(_ points: T) -> Self { width(points) height(points) return self @@ -49,7 +49,7 @@ public extension UIView { */ @discardableResult - func size(_ points: Int) -> Self { + func size(_ points: T) -> Self { size(Double(points)) } @@ -73,8 +73,8 @@ public extension UIView { */ @discardableResult - func height(_ points: Double) -> Self { - size(.height, points: points) + func height(_ points: T) -> Self { + size(.height, points: Double(points)) } /** @@ -97,8 +97,8 @@ public extension UIView { */ @discardableResult - func height(_ points: Int) -> Self { - size(.height, points: Double(points)) + func height(_ points: T) -> Self { + height(Double(points)) } /** diff --git a/Sources/Stevia/Stevia+Stacks.swift b/Sources/Stevia/Stevia+Stacks.swift index 5f1b0cd1..e16b1559 100644 --- a/Sources/Stevia/Stevia+Stacks.swift +++ b/Sources/Stevia/Stevia+Stacks.swift @@ -19,8 +19,20 @@ extension SteviaLayoutItem { } extension UIView: SteviaLayoutItem {} extension Int: SteviaLayoutItem {} +extension Int8: SteviaLayoutItem {} +extension Int16: SteviaLayoutItem {} +extension Int32: SteviaLayoutItem {} +extension Int64: SteviaLayoutItem {} +extension UInt: SteviaLayoutItem {} +extension UInt8: SteviaLayoutItem {} +extension UInt16: SteviaLayoutItem {} +extension UInt32: SteviaLayoutItem {} +extension UInt64: SteviaLayoutItem {} extension Double: SteviaLayoutItem {} +extension Float: SteviaLayoutItem {} +extension CGFloat: SteviaLayoutItem {} extension String: SteviaLayoutItem {} + extension FlexibleSpace: SteviaLayoutItem {} extension SteviaFlexibleMargin: SteviaLayoutItem {} extension SteviaPercentage: SteviaLayoutItem {} @@ -30,7 +42,6 @@ public struct FlexibleSpace { public init() {} } - @_functionBuilder public struct SteviaLayoutBuilder { public static func buildBlock(_ content: SteviaLayoutItem...) -> [SteviaLayoutItem] { return content diff --git a/Tests/SteviaTests/FullLayoutTests.swift b/Tests/SteviaTests/FullLayoutTests.swift index 6eff67b9..1066ae4f 100644 --- a/Tests/SteviaTests/FullLayoutTests.swift +++ b/Tests/SteviaTests/FullLayoutTests.swift @@ -28,10 +28,10 @@ class TestView: UIView { } Layout { - 100 + 100.5 |-email-22-| ~ 10% 20 - |password.width(54) ~ 47 + |password.width(54) ~ 47.0 >=0 login.centerHorizontally() ~ 99 7 @@ -84,7 +84,7 @@ class FullLayoutTests: XCTestCase { v.layoutIfNeeded() // Email - XCTAssertEqual(v.email.frame.origin.y, 100, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.email.frame.origin.y, 100.5, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(v.email.frame.origin.x, 8, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(v.email.frame.width, win.frame.width - 8 - 22, accuracy: CGFloat(Float.ulpOfOne)) @@ -120,7 +120,7 @@ class FullLayoutTests: XCTestCase { v.layoutIfNeeded() // Email - XCTAssertEqual(v.email.frame.origin.y, 100, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.email.frame.origin.y, 100.5, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(v.email.frame.origin.x, 22, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(v.email.frame.width, win.frame.width - 8 - 22, accuracy: CGFloat(Float.ulpOfOne)) diff --git a/Tests/SteviaTests/LayoutTests.swift b/Tests/SteviaTests/LayoutTests.swift index 79add5f5..7ec5c7b2 100644 --- a/Tests/SteviaTests/LayoutTests.swift +++ b/Tests/SteviaTests/LayoutTests.swift @@ -67,8 +67,26 @@ class LayoutTests: XCTestCase { XCTAssertEqual(v.frame.height, 0, accuracy: CGFloat(Float.ulpOfOne)) } - func testLeftMargin() { - |-75-v + func testLeftMarginDouble() { + |-Double(75)-v + ctrler.view.layoutIfNeeded() + XCTAssertEqual(v.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.origin.x, 75, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.width, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.height, 0, accuracy: CGFloat(Float.ulpOfOne)) + } + + func testLeftMarginCGFloat() { + |-CGFloat(75)-v + ctrler.view.layoutIfNeeded() + XCTAssertEqual(v.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.origin.x, 75, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.width, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.height, 0, accuracy: CGFloat(Float.ulpOfOne)) + } + + func testLeftMarginInt() { + |-Int(75)-v ctrler.view.layoutIfNeeded() XCTAssertEqual(v.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(v.frame.origin.x, 75, accuracy: CGFloat(Float.ulpOfOne)) @@ -128,8 +146,28 @@ class LayoutTests: XCTestCase { XCTAssertEqual(v.frame.height, 0, accuracy: CGFloat(Float.ulpOfOne)) } - func testRightMargin() { - v-14-| + func testRightMarginDouble() { + v-Double(14)-| + ctrler.view.layoutIfNeeded() + XCTAssertEqual(v.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.origin.x, ctrler.view.frame.width - v.frame.width - 14, + accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.width, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.height, 0, accuracy: CGFloat(Float.ulpOfOne)) + } + + func testRightMarginCGFloat() { + v-CGFloat(14)-| + ctrler.view.layoutIfNeeded() + XCTAssertEqual(v.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.origin.x, ctrler.view.frame.width - v.frame.width - 14, + accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.width, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.height, 0, accuracy: CGFloat(Float.ulpOfOne)) + } + + func testRightMarginInt() { + v-Int(14)-| ctrler.view.layoutIfNeeded() XCTAssertEqual(v.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(v.frame.origin.x, ctrler.view.frame.width - v.frame.width - 14, @@ -149,8 +187,8 @@ class LayoutTests: XCTestCase { XCTAssertEqual(v.frame.height, 0, accuracy: CGFloat(Float.ulpOfOne)) } - func testHeight() { - v ~ 180 + func testHeightDouble() { + v ~ Double(180) ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(v.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) @@ -158,8 +196,44 @@ class LayoutTests: XCTestCase { XCTAssertEqual(v.frame.height, 180, accuracy: CGFloat(Float.ulpOfOne)) } - func testHeightPercentage() { - v ~ 25% + func testHeightCGFloat() { + v ~ CGFloat(180) + ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in + XCTAssertEqual(v.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.width, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.height, 180, accuracy: CGFloat(Float.ulpOfOne)) + } + + func testHeightInt() { + v ~ Int(180) + ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in + XCTAssertEqual(v.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.width, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.height, 180, accuracy: CGFloat(Float.ulpOfOne)) + } + + func testHeightPercentageDouble() { + v ~ Double(25)% + ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in + XCTAssertEqual(v.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.width, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.height, ctrler.view.frame.height*0.25, accuracy: 0.5) + } + + func testHeightPercentageCGFloat() { + v ~ CGFloat(25)% + ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in + XCTAssertEqual(v.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.width, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.height, ctrler.view.frame.height*0.25, accuracy: 0.5) + } + + func testHeightPercentageInt() { + v ~ Int(25)% ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(v.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) @@ -167,7 +241,33 @@ class LayoutTests: XCTestCase { XCTAssertEqual(v.frame.height, ctrler.view.frame.height*0.25, accuracy: 0.5) } - func testMultipleHeightsAtOnce() { + func testMultipleHeightsAtOnceDouble() { + let v1 = UIView() + let v2 = UIView() + let v3 = UIView() + v.removeFromSuperview() + ctrler.view.Subviews { + v1 + v2 + v3 + } + for view in ctrler.view.subviews { + XCTAssertEqual(view.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(view.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(view.frame.width, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(view.frame.height, 0, accuracy: CGFloat(Float.ulpOfOne)) + } + [v1, v2, v3] ~ Double(63) + ctrler.view.layoutIfNeeded() + for view in ctrler.view.subviews { + XCTAssertEqual(view.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(view.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(view.frame.width, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(view.frame.height, 63, accuracy: CGFloat(Float.ulpOfOne)) + } + } + + func testMultipleHeightsAtOnceCGFloat() { let v1 = UIView() let v2 = UIView() let v3 = UIView() @@ -183,7 +283,33 @@ class LayoutTests: XCTestCase { XCTAssertEqual(view.frame.width, 0, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(view.frame.height, 0, accuracy: CGFloat(Float.ulpOfOne)) } - [v1, v2, v3] ~ 63 + [v1, v2, v3] ~ CGFloat(63) + ctrler.view.layoutIfNeeded() + for view in ctrler.view.subviews { + XCTAssertEqual(view.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(view.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(view.frame.width, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(view.frame.height, 63, accuracy: CGFloat(Float.ulpOfOne)) + } + } + + func testMultipleHeightsAtOnceInt() { + let v1 = UIView() + let v2 = UIView() + let v3 = UIView() + v.removeFromSuperview() + ctrler.view.Subviews { + v1 + v2 + v3 + } + for view in ctrler.view.subviews { + XCTAssertEqual(view.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(view.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(view.frame.width, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(view.frame.height, 0, accuracy: CGFloat(Float.ulpOfOne)) + } + [v1, v2, v3] ~ Int(63) ctrler.view.layoutIfNeeded() for view in ctrler.view.subviews { XCTAssertEqual(view.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) @@ -250,7 +376,7 @@ class LayoutTests: XCTestCase { XCTAssertEqual(v2.frame.height, 0, accuracy: CGFloat(Float.ulpOfOne)) } - func testMarginBetweenTwoViews() { + func testMarginBetweenTwoViewsDouble() { let v1 = UIView() let v2 = UIView() v.removeFromSuperview() @@ -264,8 +390,8 @@ class LayoutTests: XCTestCase { XCTAssertEqual(view.frame.width, 0, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(view.frame.height, 0, accuracy: CGFloat(Float.ulpOfOne)) } - - |v1.width(10)-52-v2 + let m: Double = 52 + |v1.width(10)-m-v2 ctrler.view.layoutIfNeeded() XCTAssertEqual(v1.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(v1.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) @@ -278,6 +404,64 @@ class LayoutTests: XCTestCase { XCTAssertEqual(v2.frame.height, 0, accuracy: CGFloat(Float.ulpOfOne)) } + func testMarginBetweenTwoViewsCGFloat() { + let v1 = UIView() + let v2 = UIView() + v.removeFromSuperview() + ctrler.view.Subviews { + v1 + v2 + } + for view in ctrler.view.subviews { + XCTAssertEqual(view.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(view.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(view.frame.width, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(view.frame.height, 0, accuracy: CGFloat(Float.ulpOfOne)) + } + + let m: CGFloat = 52 + |v1.width(10)-m-v2 + ctrler.view.layoutIfNeeded() + XCTAssertEqual(v1.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v1.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v1.frame.width, 10, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v1.frame.height, 0, accuracy: CGFloat(Float.ulpOfOne)) + + XCTAssertEqual(v2.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v2.frame.origin.x, 62, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v2.frame.width, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v2.frame.height, 0, accuracy: CGFloat(Float.ulpOfOne)) + } + + func testMarginBetweenTwoViewsInt() { + let v1 = UIView() + let v2 = UIView() + v.removeFromSuperview() + ctrler.view.Subviews { + v1 + v2 + } + for view in ctrler.view.subviews { + XCTAssertEqual(view.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(view.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(view.frame.width, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(view.frame.height, 0, accuracy: CGFloat(Float.ulpOfOne)) + } + + let m: Int = 52 + |v1.width(10)-m-v2 + ctrler.view.layoutIfNeeded() + XCTAssertEqual(v1.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v1.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v1.frame.width, 10, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v1.frame.height, 0, accuracy: CGFloat(Float.ulpOfOne)) + + XCTAssertEqual(v2.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v2.frame.origin.x, 62, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v2.frame.width, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v2.frame.height, 0, accuracy: CGFloat(Float.ulpOfOne)) + } + func testMarginBetweenTwoViewsRTL() { ctrler.view.semanticContentAttribute = .forceRightToLeft let v1 = UIView() @@ -407,7 +591,7 @@ class LayoutTests: XCTestCase { } - func testMarginsBetweenThreeViews() { + func testMarginsBetweenThreeViewsDouble() { let v1 = UIView() let v2 = UIView() let v3 = UIView() @@ -424,7 +608,90 @@ class LayoutTests: XCTestCase { XCTAssertEqual(view.frame.height, 0, accuracy: CGFloat(Float.ulpOfOne)) } - |v1.width(20)-43-v2.width(20)-27-v3 + let m1: Double = 43 + let m2: Double = 27 + + |v1.width(20)-m1-v2.width(20)-m2-v3 + ctrler.view.layoutIfNeeded() + XCTAssertEqual(v1.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v1.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v1.frame.width, 20, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v1.frame.height, 0, accuracy: CGFloat(Float.ulpOfOne)) + + XCTAssertEqual(v2.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v2.frame.origin.x, v1.frame.origin.x + v1.frame.width + 43, + accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v2.frame.width, 20, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v2.frame.height, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v3.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v3.frame.origin.x, v2.frame.origin.x + v2.frame.width + 27, + accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v3.frame.width, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v3.frame.height, 0, accuracy: CGFloat(Float.ulpOfOne)) + + } + + func testMarginsBetweenThreeViewsCGFloat() { + let v1 = UIView() + let v2 = UIView() + let v3 = UIView() + v.removeFromSuperview() + ctrler.view.Subviews { + v1 + v2 + v3 + } + for view in ctrler.view.subviews { + XCTAssertEqual(view.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(view.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(view.frame.width, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(view.frame.height, 0, accuracy: CGFloat(Float.ulpOfOne)) + } + + let m1: CGFloat = 43 + let m2: CGFloat = 27 + + |v1.width(20)-m1-v2.width(20)-m2-v3 + ctrler.view.layoutIfNeeded() + XCTAssertEqual(v1.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v1.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v1.frame.width, 20, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v1.frame.height, 0, accuracy: CGFloat(Float.ulpOfOne)) + + XCTAssertEqual(v2.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v2.frame.origin.x, v1.frame.origin.x + v1.frame.width + 43, + accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v2.frame.width, 20, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v2.frame.height, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v3.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v3.frame.origin.x, v2.frame.origin.x + v2.frame.width + 27, + accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v3.frame.width, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v3.frame.height, 0, accuracy: CGFloat(Float.ulpOfOne)) + + } + + func testMarginsBetweenThreeViewsInt() { + let v1 = UIView() + let v2 = UIView() + let v3 = UIView() + v.removeFromSuperview() + ctrler.view.Subviews { + v1 + v2 + v3 + } + for view in ctrler.view.subviews { + XCTAssertEqual(view.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(view.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(view.frame.width, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(view.frame.height, 0, accuracy: CGFloat(Float.ulpOfOne)) + } + + let m1: Int = 43 + let m2: Int = 27 + + |v1.width(20)-m1-v2.width(20)-m2-v3 ctrler.view.layoutIfNeeded() XCTAssertEqual(v1.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(v1.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) diff --git a/Tests/SteviaTests/PositionTests.swift b/Tests/SteviaTests/PositionTests.swift index edfc88ea..1edc12ee 100644 --- a/Tests/SteviaTests/PositionTests.swift +++ b/Tests/SteviaTests/PositionTests.swift @@ -29,8 +29,8 @@ class PositionTests: XCTestCase { super.tearDown() } - func testTop() { - v.top(23) + func testTopDouble() { + v.top(Double(23)) ctrler.view.layoutIfNeeded() XCTAssertEqual(v.frame.origin.y, 23, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(v.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) @@ -38,8 +38,26 @@ class PositionTests: XCTestCase { XCTAssertEqual(v.frame.height, 100, accuracy: CGFloat(Float.ulpOfOne)) } - func testBottom() { - v.bottom(45) + func testTopCGFloat() { + v.top(CGFloat(23)) + ctrler.view.layoutIfNeeded() + XCTAssertEqual(v.frame.origin.y, 23, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.width, 100, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.height, 100, accuracy: CGFloat(Float.ulpOfOne)) + } + + func testTopInt() { + v.top(Int(23)) + ctrler.view.layoutIfNeeded() + XCTAssertEqual(v.frame.origin.y, 23, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.width, 100, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.height, 100, accuracy: CGFloat(Float.ulpOfOne)) + } + + func testBottomDouble() { + v.bottom(Double(45)) ctrler.view.layoutIfNeeded() XCTAssertEqual(v.frame.origin.y, ctrler.view.frame.height - v.frame.height - 45, accuracy: CGFloat(Float.ulpOfOne)) @@ -48,8 +66,55 @@ class PositionTests: XCTestCase { XCTAssertEqual(v.frame.height, 100, accuracy: CGFloat(Float.ulpOfOne)) } - func testLeft() { - v.left(12) + func testBottomCGFloat() { + v.bottom(CGFloat(45)) + ctrler.view.layoutIfNeeded() + XCTAssertEqual(v.frame.origin.y, ctrler.view.frame.height - v.frame.height - 45, + accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.width, 100, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.height, 100, accuracy: CGFloat(Float.ulpOfOne)) + } + + func testBottomInt() { + v.bottom(Int(45)) + ctrler.view.layoutIfNeeded() + XCTAssertEqual(v.frame.origin.y, ctrler.view.frame.height - v.frame.height - 45, + accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.width, 100, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.height, 100, accuracy: CGFloat(Float.ulpOfOne)) + } + + func testLeftDouble() { + v.left(Double(12)) + ctrler.view.layoutIfNeeded() + XCTAssertEqual(v.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.origin.x, 12, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.width, 100, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.height, 100, accuracy: CGFloat(Float.ulpOfOne)) + } + + func testLeftCGFloat() { + v.left(CGFloat(12)) + ctrler.view.layoutIfNeeded() + XCTAssertEqual(v.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.origin.x, 12, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.width, 100, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.height, 100, accuracy: CGFloat(Float.ulpOfOne)) + } + + func testLeftInt() { + v.left(Int(12)) + ctrler.view.layoutIfNeeded() + XCTAssertEqual(v.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.origin.x, 12, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.width, 100, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.height, 100, accuracy: CGFloat(Float.ulpOfOne)) + } + + func testLeadingDouble() { + v.leading(Double(12)) ctrler.view.layoutIfNeeded() XCTAssertEqual(v.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(v.frame.origin.x, 12, accuracy: CGFloat(Float.ulpOfOne)) @@ -57,8 +122,8 @@ class PositionTests: XCTestCase { XCTAssertEqual(v.frame.height, 100, accuracy: CGFloat(Float.ulpOfOne)) } - func testLeading() { - v.leading(12) + func testLeadingCGFloat() { + v.leading(CGFloat(12)) ctrler.view.layoutIfNeeded() XCTAssertEqual(v.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(v.frame.origin.x, 12, accuracy: CGFloat(Float.ulpOfOne)) @@ -66,8 +131,57 @@ class PositionTests: XCTestCase { XCTAssertEqual(v.frame.height, 100, accuracy: CGFloat(Float.ulpOfOne)) } - func testRight() { - v.right(74) + func testLeadingInt() { + v.leading(Int(12)) + ctrler.view.layoutIfNeeded() + XCTAssertEqual(v.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.origin.x, 12, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.width, 100, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.height, 100, accuracy: CGFloat(Float.ulpOfOne)) + } + + func testRightDouble() { + v.right(Double(74)) + ctrler.view.layoutIfNeeded() + XCTAssertEqual(v.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.origin.x, ctrler.view.frame.width - v.frame.width - 74, + accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.width, 100, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.height, 100, accuracy: CGFloat(Float.ulpOfOne)) + } + + func testRightCGFloat() { + v.right(CGFloat(74)) + ctrler.view.layoutIfNeeded() + XCTAssertEqual(v.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.origin.x, ctrler.view.frame.width - v.frame.width - 74, + accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.width, 100, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.height, 100, accuracy: CGFloat(Float.ulpOfOne)) + } + + func testRightInt() { + v.right(Int(74)) + ctrler.view.layoutIfNeeded() + XCTAssertEqual(v.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.origin.x, ctrler.view.frame.width - v.frame.width - 74, + accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.width, 100, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.height, 100, accuracy: CGFloat(Float.ulpOfOne)) + } + + func testTrailingDouble() { + v.trailing(Double(74)) + ctrler.view.layoutIfNeeded() + XCTAssertEqual(v.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.origin.x, ctrler.view.frame.width - v.frame.width - 74, + accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.width, 100, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.height, 100, accuracy: CGFloat(Float.ulpOfOne)) + } + + func testTrailingCGFloat() { + v.trailing(CGFloat(74)) ctrler.view.layoutIfNeeded() XCTAssertEqual(v.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(v.frame.origin.x, ctrler.view.frame.width - v.frame.width - 74, @@ -76,8 +190,8 @@ class PositionTests: XCTestCase { XCTAssertEqual(v.frame.height, 100, accuracy: CGFloat(Float.ulpOfOne)) } - func testTrailing() { - v.trailing(74) + func testTrailingInt() { + v.trailing(Int(74)) ctrler.view.layoutIfNeeded() XCTAssertEqual(v.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(v.frame.origin.x, ctrler.view.frame.width - v.frame.width - 74, diff --git a/Tests/SteviaTests/SizeTests.swift b/Tests/SteviaTests/SizeTests.swift index 62d020c1..dc835cdd 100644 --- a/Tests/SteviaTests/SizeTests.swift +++ b/Tests/SteviaTests/SizeTests.swift @@ -30,17 +30,26 @@ class SizeTests: XCTestCase { super.tearDown() } - func testSize() { - v.size(57) - -// v.width(1) -// v.width(1.0) -// v.width(CGFloat(1)) -// v.width(Float(1)) -// v.width(Double(1)) -// v.width(Int(1)) -// v.width(UInt(1)) - + func testSizeDouble() { + v.size(Double(57)) + ctrler.view.layoutIfNeeded() + XCTAssertEqual(v.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.width, 57, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.height, 57, accuracy: CGFloat(Float.ulpOfOne)) + } + + func testSizeCGFloat() { + v.size(CGFloat(57)) + ctrler.view.layoutIfNeeded() + XCTAssertEqual(v.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.width, 57, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.height, 57, accuracy: CGFloat(Float.ulpOfOne)) + } + + func testSizeInt() { + v.size(Int(57)) ctrler.view.layoutIfNeeded() XCTAssertEqual(v.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(v.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) @@ -48,9 +57,29 @@ class SizeTests: XCTestCase { XCTAssertEqual(v.frame.height, 57, accuracy: CGFloat(Float.ulpOfOne)) } - func testWidthAndHeight() { - v.width(36) - v.height(23) + func testWidthAndHeightDouble() { + v.width(Double(36)) + v.height(Double(23)) + ctrler.view.layoutIfNeeded() + XCTAssertEqual(v.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.width, 36, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.height, 23, accuracy: CGFloat(Float.ulpOfOne)) + } + + func testWidthAndHeightCGFloat() { + v.width(CGFloat(36)) + v.height(CGFloat(23)) + ctrler.view.layoutIfNeeded() + XCTAssertEqual(v.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.width, 36, accuracy: CGFloat(Float.ulpOfOne)) + XCTAssertEqual(v.frame.height, 23, accuracy: CGFloat(Float.ulpOfOne)) + } + + func testWidthAndHeightInt() { + v.width(Int(36)) + v.height(Int(23)) ctrler.view.layoutIfNeeded() XCTAssertEqual(v.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(v.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) diff --git a/Tests/SteviaTests/SteviaTests.swift b/Tests/SteviaTests/SteviaTests.swift deleted file mode 100644 index ec31de0b..00000000 --- a/Tests/SteviaTests/SteviaTests.swift +++ /dev/null @@ -1,14 +0,0 @@ -import XCTest -@testable import Stevia - -final class SteviaTests: XCTestCase { - func testExample() { - // This is an example of a functional test case. - // Use XCTAssert and related functions to verify your tests produce the correct - // results. - } - - static var allTests = [ - ("testExample", testExample), - ] -} From 573a01f7d1bce9dbd34b61672186bc95bbcfde38 Mon Sep 17 00:00:00 2001 From: S4cha Date: Thu, 2 Apr 2020 15:08:12 +0200 Subject: [PATCH 06/12] Update Stevia+DoubleDash.swift --- Sources/Stevia/Stevia+DoubleDash.swift | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/Sources/Stevia/Stevia+DoubleDash.swift b/Sources/Stevia/Stevia+DoubleDash.swift index db87d5da..abf1ced0 100644 --- a/Sources/Stevia/Stevia+DoubleDash.swift +++ b/Sources/Stevia/Stevia+DoubleDash.swift @@ -12,8 +12,12 @@ import UIKit infix operator -- :AdditionPrecedence @discardableResult -public func -- (left: UIView, right: Double) -> PartialConstraint { - return left-right +public func -- (left: UIView, right: T) -> PartialConstraint { + return left-Double(right) +} + +public func -- (left: UIView, right: T) -> PartialConstraint { + return left--Double(right) } @discardableResult @@ -42,8 +46,13 @@ public func -- (left: UIView, right: UIView) -> [UIView] { } @discardableResult -public func -- (left: [UIView], right: Double) -> PartialConstraint { - return left-right +public func -- (left: [UIView], right: T) -> PartialConstraint { + return left-Double(right) +} + +@discardableResult +public func -- (left: [UIView], right: T) -> PartialConstraint { + return left--Double(right) } @discardableResult From 3aa987370002e569b34093e616fe95b3eb69f4c8 Mon Sep 17 00:00:00 2001 From: S4cha Date: Thu, 2 Apr 2020 15:09:00 +0200 Subject: [PATCH 07/12] WIP --- Sources/Stevia/Stevia+Stacks.swift | 24 ++++++++++++------------ Tests/SteviaTests/LayoutTests.swift | 11 +++++++++++ 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/Sources/Stevia/Stevia+Stacks.swift b/Sources/Stevia/Stevia+Stacks.swift index e16b1559..0fd27aa2 100644 --- a/Sources/Stevia/Stevia+Stacks.swift +++ b/Sources/Stevia/Stevia+Stacks.swift @@ -19,19 +19,19 @@ extension SteviaLayoutItem { } extension UIView: SteviaLayoutItem {} extension Int: SteviaLayoutItem {} -extension Int8: SteviaLayoutItem {} -extension Int16: SteviaLayoutItem {} -extension Int32: SteviaLayoutItem {} -extension Int64: SteviaLayoutItem {} -extension UInt: SteviaLayoutItem {} -extension UInt8: SteviaLayoutItem {} -extension UInt16: SteviaLayoutItem {} -extension UInt32: SteviaLayoutItem {} -extension UInt64: SteviaLayoutItem {} +//extension Int8: SteviaLayoutItem {} +//extension Int16: SteviaLayoutItem {} +//extension Int32: SteviaLayoutItem {} +//extension Int64: SteviaLayoutItem {} +//extension UInt: SteviaLayoutItem {} +//extension UInt8: SteviaLayoutItem {} +//extension UInt16: SteviaLayoutItem {} +//extension UInt32: SteviaLayoutItem {} +//extension UInt64: SteviaLayoutItem {} extension Double: SteviaLayoutItem {} -extension Float: SteviaLayoutItem {} -extension CGFloat: SteviaLayoutItem {} -extension String: SteviaLayoutItem {} +//extension Float: SteviaLayoutItem {} +//extension CGFloat: SteviaLayoutItem {} +//extension String: SteviaLayoutItem {} extension FlexibleSpace: SteviaLayoutItem {} extension SteviaFlexibleMargin: SteviaLayoutItem {} diff --git a/Tests/SteviaTests/LayoutTests.swift b/Tests/SteviaTests/LayoutTests.swift index 7ec5c7b2..433cc386 100644 --- a/Tests/SteviaTests/LayoutTests.swift +++ b/Tests/SteviaTests/LayoutTests.swift @@ -29,6 +29,17 @@ class LayoutTests: XCTestCase { super.tearDown() } + func testComplexLayout() { + let featureA = UIView() + let featureB = UIView() + + let m1:Int = 6 + let m2:Int = 2 +// |-6-featureA-2-featureB-6-| + |-m1-featureA-m2-featureB-m1-| + //align(horizontally: |-6-feature1-2-feature2-6-|) + } + func testEmptyLeftMargin() { |v ctrler.view.layoutIfNeeded() From 5b232409a2b41520c56f4660f4006ffc8587e89f Mon Sep 17 00:00:00 2001 From: S4cha Date: Fri, 3 Apr 2020 16:18:00 +0200 Subject: [PATCH 08/12] Rollback BinaryFloating/Integer to Native type for better compile time --- Sources/Stevia/Stevia+Center.swift | 36 +++--- Sources/Stevia/Stevia+DoubleDash.swift | 43 ++++++- Sources/Stevia/Stevia+Equation.swift | 84 +++++++++---- Sources/Stevia/Stevia+Fill.swift | 46 +++---- Sources/Stevia/Stevia+FlexibleMargin.swift | 22 +++- Sources/Stevia/Stevia+Hierarchy.swift | 2 +- Sources/Stevia/Stevia+Operators.swift | 63 +++++++--- Sources/Stevia/Stevia+Percentage.swift | 8 +- Sources/Stevia/Stevia+Position.swift | 132 ++++++++++++++++++--- Sources/Stevia/Stevia+Size.swift | 78 ++++++++++-- Sources/Stevia/Stevia+Stacks.swift | 16 +-- 11 files changed, 398 insertions(+), 132 deletions(-) diff --git a/Sources/Stevia/Stevia+Center.swift b/Sources/Stevia/Stevia+Center.swift index fb3c783f..471ab887 100644 --- a/Sources/Stevia/Stevia+Center.swift +++ b/Sources/Stevia/Stevia+Center.swift @@ -28,7 +28,7 @@ public extension UIView { } return self } - + /** Centers the view horizontally (X axis) in its container. @@ -41,8 +41,11 @@ public extension UIView { */ @discardableResult - func centerHorizontally() -> Self { - centerHorizontally(offset: 0) + func centerHorizontally(offset: Double = 0) -> Self { + if let spv = superview { + align(.vertical, v1: self, with: spv, offset: offset) + } + return self } /** @@ -57,11 +60,8 @@ public extension UIView { */ @discardableResult - func centerHorizontally(offset: T) -> Self { - if let spv = superview { - align(.vertical, v1: self, with: spv, offset: Double(offset)) - } - return self + func centerHorizontally(offset: CGFloat) -> Self { + centerHorizontally(offset: Double(offset)) } /** @@ -76,10 +76,10 @@ public extension UIView { */ @discardableResult - func centerHorizontally(offset: T) -> Self { + func centerHorizontally(offset: Int) -> Self { centerHorizontally(offset: Double(offset)) } - + /** Centers the view vertically (Y axis) in its container. @@ -92,8 +92,11 @@ public extension UIView { */ @discardableResult - func centerVertically() -> Self { - centerVertically(offset: 0) + func centerVertically(offset: Double = 0) -> Self { + if let spv = superview { + align(.horizontal, v1: self, with: spv, offset: offset) + } + return self } /** @@ -108,11 +111,8 @@ public extension UIView { */ @discardableResult - func centerVertically(offset: T) -> Self { - if let spv = superview { - align(.horizontal, v1: self, with: spv, offset: Double(offset)) - } - return self + func centerVertically(offset: CGFloat) -> Self { + centerVertically(offset: Double(offset)) } /** @@ -127,7 +127,7 @@ public extension UIView { */ @discardableResult - func centerVertically(offset: T) -> Self { + func centerVertically(offset: Int) -> Self { centerVertically(offset: Double(offset)) } } diff --git a/Sources/Stevia/Stevia+DoubleDash.swift b/Sources/Stevia/Stevia+DoubleDash.swift index abf1ced0..8d483e48 100644 --- a/Sources/Stevia/Stevia+DoubleDash.swift +++ b/Sources/Stevia/Stevia+DoubleDash.swift @@ -11,97 +11,128 @@ import UIKit infix operator -- :AdditionPrecedence + +@available(*, deprecated, renamed: "⁃") @discardableResult -public func -- (left: UIView, right: T) -> PartialConstraint { - return left-Double(right) +public func -- (left: UIView, right: Double) -> PartialConstraint { + return left-right +} + +@available(*, deprecated, renamed: "⁃") +public func -- (left: UIView, right: CGFloat) -> PartialConstraint { + return left--Double(right) } -public func -- (left: UIView, right: T) -> PartialConstraint { +@available(*, deprecated, renamed: "⁃") +public func -- (left: UIView, right: Int) -> PartialConstraint { return left--Double(right) } +@available(*, deprecated, renamed: "⁃") @discardableResult public func -- (left: SideConstraint, right: UIView) -> UIView { return left-right } +@available(*, deprecated, renamed: "⁃") @discardableResult public func -- (left: [UIView], right: SideConstraint) -> [UIView] { return left-right } +@available(*, deprecated, renamed: "⁃") @discardableResult public func -- (left: UIView, right: SideConstraint) -> UIView { return left-right } +@available(*, deprecated, renamed: "⁃") @discardableResult public func -- (left: PartialConstraint, right: UIView) -> [UIView] { return left-right } +@available(*, deprecated, renamed: "⁃") @discardableResult public func -- (left: UIView, right: UIView) -> [UIView] { return left-right } +@available(*, deprecated, renamed: "⁃") @discardableResult -public func -- (left: [UIView], right: T) -> PartialConstraint { - return left-Double(right) +public func -- (left: [UIView], right: Double) -> PartialConstraint { + return left-right +} + +@available(*, deprecated, renamed: "⁃") +@discardableResult +public func -- (left: [UIView], right: CGFloat) -> PartialConstraint { + return left--Double(right) } +@available(*, deprecated, renamed: "⁃") @discardableResult -public func -- (left: [UIView], right: T) -> PartialConstraint { +public func -- (left: [UIView], right: Int) -> PartialConstraint { return left--Double(right) } +@available(*, deprecated, renamed: "⁃") @discardableResult public func -- (left: [UIView], right: UIView) -> [UIView] { return left-right } +@available(*, deprecated, renamed: "⁃") @discardableResult public func -- (left: UIView, right: String) -> Space { return left-right } +@available(*, deprecated, renamed: "⁃") @discardableResult public func -- (left: [UIView], right: String) -> Space { return left-right } +@available(*, deprecated, renamed: "⁃") @discardableResult public func -- (left: Space, right: UIView) -> [UIView] { return left-right } +@available(*, deprecated, renamed: "⁃") @discardableResult public func -- (left: UIView, right: SteviaFlexibleMargin) -> PartialFlexibleConstraint { return left-right } +@available(*, deprecated, renamed: "⁃") @discardableResult public func -- (left: [UIView], right: SteviaFlexibleMargin) -> PartialFlexibleConstraint { return left-right } +@available(*, deprecated, renamed: "⁃") @discardableResult public func -- (left: PartialFlexibleConstraint, right: UIView) -> [UIView] { return left-right } +@available(*, deprecated, renamed: "⁃") @discardableResult public func -- (left: SteviaLeftFlexibleMargin, right: UIView) -> UIView { return left-right } +@available(*, deprecated, renamed: "⁃") @discardableResult public func -- (left: UIView, right: SteviaRightFlexibleMargin) -> UIView { return left-right } +@available(*, deprecated, renamed: "⁃") @discardableResult public func -- (left: [UIView], right: SteviaRightFlexibleMargin) -> [UIView] { return left-right diff --git a/Sources/Stevia/Stevia+Equation.swift b/Sources/Stevia/Stevia+Equation.swift index 3591af6f..9a35b15b 100644 --- a/Sources/Stevia/Stevia+Equation.swift +++ b/Sources/Stevia/Stevia+Equation.swift @@ -183,59 +183,86 @@ private func applyRelation(left: SteviaAttribute, right: SteviaAttribute, relate } @discardableResult -public func + (left: SteviaAttribute, right: T) -> SteviaAttribute { - SteviaAttribute(view: left.view, attribute: left.attribute, constant: Double(right), multiplier: left.multiplier) +public func + (left: SteviaAttribute, right: Double) -> SteviaAttribute { + SteviaAttribute(view: left.view, attribute: left.attribute, constant: right, multiplier: left.multiplier) } @discardableResult -public func + (left: SteviaAttribute, right: T) -> SteviaAttribute { +public func + (left: SteviaAttribute, right: CGFloat) -> SteviaAttribute { left + Double(right) } @discardableResult -public func - (left: SteviaAttribute, right: T) -> SteviaAttribute { - SteviaAttribute(view: left.view, attribute: left.attribute, constant: -Double(right), multiplier: left.multiplier) +public func + (left: SteviaAttribute, right: Int) -> SteviaAttribute { + left + Double(right) } @discardableResult -public func - (left: SteviaAttribute, right: T) -> SteviaAttribute { +public func - (left: SteviaAttribute, right: Double) -> SteviaAttribute { + SteviaAttribute(view: left.view, attribute: left.attribute, constant: -right, multiplier: left.multiplier) +} + +@discardableResult +public func - (left: SteviaAttribute, right: CGFloat) -> SteviaAttribute { left - Double(right) } @discardableResult -public func * (left: SteviaAttribute, right: T) -> SteviaAttribute { - SteviaAttribute(view: left.view, attribute: left.attribute, constant: left.constant, multiplier: Double(right)) +public func - (left: SteviaAttribute, right: Int) -> SteviaAttribute { + left - Double(right) } @discardableResult -public func * (left: SteviaAttribute, right: T) -> SteviaAttribute { +public func * (left: SteviaAttribute, right: Double) -> SteviaAttribute { + SteviaAttribute(view: left.view, attribute: left.attribute, constant: left.constant, multiplier: right) +} + +@discardableResult +public func * (left: SteviaAttribute, right: CGFloat) -> SteviaAttribute { left * Double(right) } @discardableResult -public func / (left: SteviaAttribute, right: T) -> SteviaAttribute { - left * (1/Double(right)) +public func * (left: SteviaAttribute, right: Int) -> SteviaAttribute { + left * Double(right) } @discardableResult -public func / (left: SteviaAttribute, right: T) -> SteviaAttribute { +public func / (left: SteviaAttribute, right: Double) -> SteviaAttribute { + left * (1/right) +} + +@discardableResult +public func / (left: SteviaAttribute, right: CGFloat) -> SteviaAttribute { + left / Double(right) +} + +@discardableResult +public func / (left: SteviaAttribute, right: Int) -> SteviaAttribute { left / Double(right) } + +@discardableResult +public func % (left: Double, right: SteviaAttribute) -> SteviaAttribute { + right * (left/100) +} + @discardableResult -public func % (left: T, right: SteviaAttribute) -> SteviaAttribute { - right * (Double(left)/100) +public func % (left: CGFloat, right: SteviaAttribute) -> SteviaAttribute { + Double(left) % right } @discardableResult -public func % (left: T, right: SteviaAttribute) -> SteviaAttribute { +public func % (left: Int, right: SteviaAttribute) -> SteviaAttribute { Double(left) % right } + // MARK: - Equations of type v.P == X @discardableResult -public func == (left: SteviaAttribute, right: T) -> NSLayoutConstraint { +public func == (left: SteviaAttribute, right: Double) -> NSLayoutConstraint { if let spv = left.view.superview { var toItem: UIView? = spv var constant = right @@ -254,12 +281,17 @@ public func == (left: SteviaAttribute, right: T) -> NSLa } @discardableResult -public func == (left: SteviaAttribute, right: T) -> NSLayoutConstraint { +public func == (left: SteviaAttribute, right: CGFloat) -> NSLayoutConstraint { + left == Double(right) +} + +@discardableResult +public func == (left: SteviaAttribute, right: Int) -> NSLayoutConstraint { left == Double(right) } @discardableResult -public func >= (left: SteviaAttribute, right: T) -> NSLayoutConstraint { +public func >= (left: SteviaAttribute, right: Double) -> NSLayoutConstraint { if let spv = left.view.superview { var toItem: UIView? = spv var constant = right @@ -279,12 +311,17 @@ public func >= (left: SteviaAttribute, right: T) -> NSLa } @discardableResult -public func >= (left: SteviaAttribute, right: T) -> NSLayoutConstraint { +public func >= (left: SteviaAttribute, right: CGFloat) -> NSLayoutConstraint { left >= Double(right) } @discardableResult -public func <= (left: SteviaAttribute, right: T) -> NSLayoutConstraint { +public func >= (left: SteviaAttribute, right: Int) -> NSLayoutConstraint { + left >= Double(right) +} + +@discardableResult +public func <= (left: SteviaAttribute, right: Double) -> NSLayoutConstraint { if let spv = left.view.superview { var toItem: UIView? = spv var constant = right @@ -304,7 +341,12 @@ public func <= (left: SteviaAttribute, right: T) -> NSLa } @discardableResult -public func <= (left: SteviaAttribute, right: T) -> NSLayoutConstraint { +public func <= (left: SteviaAttribute, right: CGFloat) -> NSLayoutConstraint { + left <= Double(right) +} + +@discardableResult +public func <= (left: SteviaAttribute, right: Int) -> NSLayoutConstraint { left <= Double(right) } #endif diff --git a/Sources/Stevia/Stevia+Fill.swift b/Sources/Stevia/Stevia+Fill.swift index 7694a91c..544bcdff 100644 --- a/Sources/Stevia/Stevia+Fill.swift +++ b/Sources/Stevia/Stevia+Fill.swift @@ -10,11 +10,15 @@ import UIKit public extension UIView { - + + /** + Adds the constraints needed for the view to fill its `superview`. + A padding can be used to apply equal spaces between the view and its superview + */ @discardableResult - func fillContainer() -> Self { - fillHorizontally() - fillVertically() + func fillContainer(padding: Double = 0) -> Self { + fillHorizontally(padding: padding) + fillVertically(padding: padding) return self } @@ -23,10 +27,8 @@ public extension UIView { A padding can be used to apply equal spaces between the view and its superview */ @discardableResult - func fillContainer(padding: T) -> Self { - fillHorizontally(padding: padding) - fillVertically(padding: padding) - return self + func fillContainer(padding: CGFloat) -> Self { + fillContainer(padding: Double(padding)) } /** @@ -34,17 +36,17 @@ public extension UIView { A padding can be used to apply equal spaces between the view and its superview */ @discardableResult - func fillContainer(padding: T) -> Self { + func fillContainer(padding: Int) -> Self { fillContainer(padding: Double(padding)) } - + /** Adds the constraints needed for the view to fill its `superview` Vertically. A padding can be used to apply equal spaces between the view and its superview */ @discardableResult - func fillVertically() -> Self { - fill(.vertical) + func fillVertically(padding: Double = 0) -> Self { + fill(.vertical, points: padding) } /** @@ -52,8 +54,8 @@ public extension UIView { A padding can be used to apply equal spaces between the view and its superview */ @discardableResult - func fillVertically(padding: T) -> Self { - fill(.vertical, points: Double(padding)) + func fillVertically(padding: CGFloat) -> Self { + fillVertically(padding: Double(padding)) } /** @@ -61,26 +63,26 @@ public extension UIView { A padding can be used to apply equal spaces between the view and its superview */ @discardableResult - func fillVertically(padding: T) -> Self { + func fillVertically(padding: Int) -> Self { fillVertically(padding: Double(padding)) } - + /** Adds the constraints needed for the view to fill its `superview` Horizontally. A padding can be used to apply equal spaces between the view and its superview */ @discardableResult - func fillHorizontally() -> Self { - fill(.horizontal) + func fillHorizontally(padding: Double = 0) -> Self { + fill(.horizontal, points: padding) } - + /** Adds the constraints needed for the view to fill its `superview` Horizontally. A padding can be used to apply equal spaces between the view and its superview */ @discardableResult - func fillHorizontally(padding: T) -> Self { - fill(.horizontal, points: Double(padding)) + func fillHorizontally(padding: CGFloat) -> Self { + fillHorizontally(padding: Double(padding)) } /** @@ -88,7 +90,7 @@ public extension UIView { A padding can be used to apply equal spaces between the view and its superview */ @discardableResult - func fillHorizontally(padding: T) -> Self { + func fillHorizontally(padding: Int) -> Self { fillHorizontally(padding: Double(padding)) } diff --git a/Sources/Stevia/Stevia+FlexibleMargin.swift b/Sources/Stevia/Stevia+FlexibleMargin.swift index 5b9ebd65..bfc32152 100644 --- a/Sources/Stevia/Stevia+FlexibleMargin.swift +++ b/Sources/Stevia/Stevia+FlexibleMargin.swift @@ -11,23 +11,33 @@ import UIKit prefix operator >= @discardableResult -public prefix func >= (p: T) -> SteviaFlexibleMargin { - SteviaFlexibleMargin(points: Double(p), relation: .greaterThanOrEqual) +public prefix func >= (p: Double) -> SteviaFlexibleMargin { + SteviaFlexibleMargin(points: p, relation: .greaterThanOrEqual) } @discardableResult -public prefix func >= (p: T) -> SteviaFlexibleMargin { +public prefix func >= (p: CGFloat) -> SteviaFlexibleMargin { + >=Double(p) +} + +@discardableResult +public prefix func >= (p: Int) -> SteviaFlexibleMargin { >=Double(p) } prefix operator <= @discardableResult -public prefix func <= (p: T) -> SteviaFlexibleMargin { - SteviaFlexibleMargin(points: Double(p), relation: .lessThanOrEqual) +public prefix func <= (p: Double) -> SteviaFlexibleMargin { + SteviaFlexibleMargin(points: p, relation: .lessThanOrEqual) +} + +@discardableResult +public prefix func <= (p: CGFloat) -> SteviaFlexibleMargin { + <=Double(p) } @discardableResult -public prefix func <= (p: T) -> SteviaFlexibleMargin { +public prefix func <= (p: Int) -> SteviaFlexibleMargin { <=Double(p) } diff --git a/Sources/Stevia/Stevia+Hierarchy.swift b/Sources/Stevia/Stevia+Hierarchy.swift index d3067eaf..56281924 100644 --- a/Sources/Stevia/Stevia+Hierarchy.swift +++ b/Sources/Stevia/Stevia+Hierarchy.swift @@ -49,7 +49,7 @@ public extension UIView { - Returns: Itself to enable nested layouts. */ - @available(*, deprecated, message: "Use Subviews { } function builder instead.") +// @available(*, deprecated, message: "Use Subviews { } function builder instead.") @discardableResult func sv(_ subViews: UIView...) -> UIView { return sv(subViews) diff --git a/Sources/Stevia/Stevia+Operators.swift b/Sources/Stevia/Stevia+Operators.swift index e736e9e0..3ecc5e76 100644 --- a/Sources/Stevia/Stevia+Operators.swift +++ b/Sources/Stevia/Stevia+Operators.swift @@ -28,16 +28,19 @@ precedencegroup HeightPrecedence { } @discardableResult -public func ~ (left: UIView, right: T) -> UIView { +public func ~ (left: UIView, right: Double) -> UIView { left.height(right) } @discardableResult -public func ~ (left: UIView, right: T) -> UIView { +public func ~ (left: UIView, right: CGFloat) -> UIView { left ~ Double(right) } - +@discardableResult +public func ~ (left: UIView, right: Int) -> UIView { + left ~ Double(right) +} @discardableResult public func ~ (left: UIView, right: SteviaPercentage) -> UIView { @@ -50,13 +53,18 @@ public func ~ (left: UIView, right: SteviaFlexibleMargin) -> UIView { } @discardableResult -public func ~ (left: [UIView], right: T) -> [UIView] { +public func ~ (left: [UIView], right: Double) -> [UIView] { for l in left { l.height(right) } return left } @discardableResult -public func ~ (left: [UIView], right: T) -> [UIView] { +public func ~ (left: [UIView], right: CGFloat) -> [UIView] { + left ~ Double(right) +} + +@discardableResult +public func ~ (left: [UIView], right: Int) -> [UIView] { left ~ Double(right) } @@ -68,14 +76,19 @@ public func ~ (left: [UIView], right: SteviaFlexibleMargin) -> [UIView] { prefix operator |- @discardableResult -public prefix func |- (p: T) -> SideConstraint { +public prefix func |- (p: Double) -> SideConstraint { var s = SideConstraint() - s.constant = Double(p) + s.constant = p return s } @discardableResult -public prefix func |- (p: T) -> SideConstraint { +public prefix func |- (p: CGFloat) -> SideConstraint { + |-Double(p) +} + +@discardableResult +public prefix func |- (p: Int) -> SideConstraint { |-Double(p) } @@ -86,14 +99,19 @@ public prefix func |- (v: UIView) -> UIView { postfix operator -| @discardableResult -public postfix func -| (p: T) -> SideConstraint { +public postfix func -| (p: Double) -> SideConstraint { var s = SideConstraint() - s.constant = Double(p) + s.constant = p return s } @discardableResult -public postfix func -| (p: T) -> SideConstraint { +public postfix func -| (p: CGFloat) -> SideConstraint { + Double(p)-| +} + +@discardableResult +public postfix func -| (p: Int) -> SideConstraint { Double(p)-| } @@ -113,15 +131,20 @@ public struct PartialConstraint { } @discardableResult -public func - (left: UIView, right: T) -> PartialConstraint { +public func - (left: UIView, right: Double) -> PartialConstraint { var p = PartialConstraint() p.view1 = left - p.constant = Double(right) + p.constant = right return p } @discardableResult -public func - (left: UIView, right: T) -> PartialConstraint { +public func - (left: UIView, right: CGFloat) -> PartialConstraint { + left-Double(right) +} + +@discardableResult +public func - (left: UIView, right: Int) -> PartialConstraint { left-Double(right) } @@ -197,18 +220,24 @@ public func - (left: UIView, right: UIView) -> [UIView] { } @discardableResult -public func - (left: [UIView], right: T) -> PartialConstraint { +public func - (left: [UIView], right: Double) -> PartialConstraint { var p = PartialConstraint() - p.constant = Double(right) + p.constant = right p.views = left return p } @discardableResult -public func - (left: [UIView], right: T) -> PartialConstraint { +public func - (left: [UIView], right: CGFloat) -> PartialConstraint { + left-Double(right) +} + +@discardableResult +public func - (left: [UIView], right: Int) -> PartialConstraint { left-Double(right) } + @discardableResult public func - (left: [UIView], right: UIView) -> [UIView] { let lastView = left[left.count-1] diff --git a/Sources/Stevia/Stevia+Percentage.swift b/Sources/Stevia/Stevia+Percentage.swift index de00fa7c..fa0d153e 100644 --- a/Sources/Stevia/Stevia+Percentage.swift +++ b/Sources/Stevia/Stevia+Percentage.swift @@ -14,11 +14,15 @@ public struct SteviaPercentage { } postfix operator % -public postfix func % (v: T) -> SteviaPercentage { +public postfix func % (v: Double) -> SteviaPercentage { SteviaPercentage(value: Double(v)) } -public postfix func % (v: T) -> SteviaPercentage { +public postfix func % (v: CGFloat) -> SteviaPercentage { + Double(v)% +} + +public postfix func % (v: Int) -> SteviaPercentage { Double(v)% } diff --git a/Sources/Stevia/Stevia+Position.swift b/Sources/Stevia/Stevia+Position.swift index ecc95d60..59ad3ea2 100644 --- a/Sources/Stevia/Stevia+Position.swift +++ b/Sources/Stevia/Stevia+Position.swift @@ -23,8 +23,8 @@ public extension UIView { - Returns: Itself for chaining purposes */ @discardableResult - func left(_ points: T) -> Self { - position(.left, points: Double(points)) + func left(_ points: Double) -> Self { + position(.left, points: points) } /** Sets the left margin for a view. @@ -39,7 +39,23 @@ public extension UIView { - Returns: Itself for chaining purposes */ @discardableResult - func left(_ points: T) -> Self { + func left(_ points: CGFloat) -> Self { + left(Double(points)) + } + + /** Sets the left margin for a view. + + Example Usage : + + label.left(20) + label.left(<=20) + label.left(>=20) + label.left(20%) + + - Returns: Itself for chaining purposes + */ + @discardableResult + func left(_ points: Int) -> Self { left(Double(points)) } @@ -55,8 +71,8 @@ public extension UIView { - Returns: Itself for chaining purposes */ @discardableResult - func right(_ points: T) -> Self { - position(.right, points: -Double(points)) + func right(_ points: Double) -> Self { + position(.right, points: -points) } /** Sets the right margin for a view. @@ -71,10 +87,42 @@ public extension UIView { - Returns: Itself for chaining purposes */ @discardableResult - func right(_ points: T) -> Self { + func right(_ points: CGFloat) -> Self { right(Double(points)) } + /** Sets the right margin for a view. + + Example Usage : + + label.right(20) + label.right(<=20) + label.right(>=20) + label.right(20%) + + - Returns: Itself for chaining purposes + */ + @discardableResult + func right(_ points: Int) -> Self { + right(Double(points)) + } + + /** Sets the top margin for a view. + + Example Usage : + + label.top(20) + label.top(<=20) + label.top(>=20) + label.top(20%) + + - Returns: Itself for chaining purposes + */ + @discardableResult + func top(_ points: Double) -> Self { + position(.top, points: points) + } + /** Sets the top margin for a view. Example Usage : @@ -87,8 +135,8 @@ public extension UIView { - Returns: Itself for chaining purposes */ @discardableResult - func top(_ points: T) -> Self { - position(.top, points: Double(points)) + func top(_ points: CGFloat) -> Self { + top(Double(points)) } /** Sets the top margin for a view. @@ -103,7 +151,7 @@ public extension UIView { - Returns: Itself for chaining purposes */ @discardableResult - func top(_ points: T) -> Self { + func top(_ points: Int) -> Self { top(Double(points)) } @@ -119,8 +167,8 @@ public extension UIView { - Returns: Itself for chaining purposes */ @discardableResult - func bottom(_ points: T) -> Self { - position(.bottom, points: -Double(points)) + func bottom(_ points: Double) -> Self { + position(.bottom, points: -points) } /** Sets the bottom margin for a view. @@ -135,7 +183,23 @@ public extension UIView { - Returns: Itself for chaining purposes */ @discardableResult - func bottom(_ points: T) -> Self { + func bottom(_ points: CGFloat) -> Self { + bottom(Double(points)) + } + + /** Sets the bottom margin for a view. + + Example Usage : + + label.bottom(20) + label.bottom(<=20) + label.bottom(>=20) + label.bottom(20%) + + - Returns: Itself for chaining purposes + */ + @discardableResult + func bottom(_ points: Int) -> Self { bottom(Double(points)) } @@ -234,8 +298,8 @@ public extension UIView { */ @discardableResult - func leading(_ points: T) -> UIView { - position(.leading, points: Double(points)) + func leading(_ points: Double) -> UIView { + position(.leading, points: points) } /** Sets the leading margin for a view. @@ -250,7 +314,23 @@ public extension UIView { - Returns: itself for chaining purposes */ @discardableResult - func leading(_ points: T) -> UIView { + func leading(_ points: CGFloat) -> UIView { + leading(Double(points)) + } + + /** Sets the leading margin for a view. + + Example Usage : + + label.leading(20) + label.leading(<=20) + label.leading(>=20) + label.leading(20%) + + - Returns: itself for chaining purposes + */ + @discardableResult + func leading(_ points: Int) -> UIView { leading(Double(points)) } @@ -271,8 +351,24 @@ public extension UIView { - Returns: itself for chaining purposes */ @discardableResult - func trailing(_ points: T) -> UIView { - position(.trailing, points: -Double(points)) + func trailing(_ points: Double) -> UIView { + position(.trailing, points: -points) + } + + /** Sets the trailing margin for a view. + + Example Usage : + + label.trailing(20) + label.trailing(<=20) + label.trailing(>=20) + label.trailing(20%) + + - Returns: itself for chaining purposes + */ + @discardableResult + func trailing(_ points: CGFloat) -> UIView { + trailing(Double(points)) } /** Sets the trailing margin for a view. @@ -287,7 +383,7 @@ public extension UIView { - Returns: itself for chaining purposes */ @discardableResult - func trailing(_ points: T) -> UIView { + func trailing(_ points: Int) -> UIView { trailing(Double(points)) } diff --git a/Sources/Stevia/Stevia+Size.swift b/Sources/Stevia/Stevia+Size.swift index 13889a55..24fd2d55 100644 --- a/Sources/Stevia/Stevia+Size.swift +++ b/Sources/Stevia/Stevia+Size.swift @@ -27,7 +27,7 @@ public extension UIView { */ @discardableResult - func size(_ points: T) -> Self { + func size(_ points: Double) -> Self { width(points) height(points) return self @@ -49,7 +49,27 @@ public extension UIView { */ @discardableResult - func size(_ points: T) -> Self { + func size(_ points: CGFloat) -> Self { + size(Double(points)) + } + + /** + Adds an Autolayout constraint for sizing the view. + + ``` + image.size(100) + image.size(100%) + + // is equivalent to + + image.width(100).height(100) + ``` + + - Returns: Itself, enabling chaining, + + */ + @discardableResult + func size(_ points: Int) -> Self { size(Double(points)) } @@ -73,8 +93,8 @@ public extension UIView { */ @discardableResult - func height(_ points: T) -> Self { - size(.height, points: Double(points)) + func height(_ points: Double) -> Self { + size(.height, points: points) } /** @@ -97,7 +117,31 @@ public extension UIView { */ @discardableResult - func height(_ points: T) -> Self { + func height(_ points: CGFloat) -> Self { + height(Double(points)) + } + + /** + Adds an Autolayout constraint for setting the view's height. + + ``` + image.height(100) + + // is equivalent to + + image ~ 100 + + // Flexible margins + image.height(<=100) + image.height(>=100) + image.height(100%) + ``` + + - Returns: Itself, enabling chaining, + + */ + @discardableResult + func height(_ points: Int) -> Self { height(Double(points)) } @@ -115,8 +159,26 @@ public extension UIView { */ @discardableResult - func width(_ points: T) -> Self { - size(.width, points: Double(points)) + func width(_ points: Double) -> Self { + size(.width, points: points) + } + + /** + Adds an Autolayout constraint for setting the view's width. + + ``` + image.width(100) + image.width(<=100) + image.width(>=100) + image.width(100%) + ``` + + - Returns: Itself, enabling chaining, + + */ + @discardableResult + func width(_ points: CGFloat) -> Self { + width(Double(points)) } /** @@ -133,7 +195,7 @@ public extension UIView { */ @discardableResult - func width(_ points: T) -> Self { + func width(_ points: Int) -> Self { width(Double(points)) } diff --git a/Sources/Stevia/Stevia+Stacks.swift b/Sources/Stevia/Stevia+Stacks.swift index 0fd27aa2..91b4fda5 100644 --- a/Sources/Stevia/Stevia+Stacks.swift +++ b/Sources/Stevia/Stevia+Stacks.swift @@ -19,19 +19,9 @@ extension SteviaLayoutItem { } extension UIView: SteviaLayoutItem {} extension Int: SteviaLayoutItem {} -//extension Int8: SteviaLayoutItem {} -//extension Int16: SteviaLayoutItem {} -//extension Int32: SteviaLayoutItem {} -//extension Int64: SteviaLayoutItem {} -//extension UInt: SteviaLayoutItem {} -//extension UInt8: SteviaLayoutItem {} -//extension UInt16: SteviaLayoutItem {} -//extension UInt32: SteviaLayoutItem {} -//extension UInt64: SteviaLayoutItem {} extension Double: SteviaLayoutItem {} -//extension Float: SteviaLayoutItem {} -//extension CGFloat: SteviaLayoutItem {} -//extension String: SteviaLayoutItem {} +extension CGFloat: SteviaLayoutItem {} +extension String: SteviaLayoutItem {} extension FlexibleSpace: SteviaLayoutItem {} extension SteviaFlexibleMargin: SteviaLayoutItem {} @@ -86,7 +76,7 @@ public extension UIView { ) ``` */ - @available(*, deprecated, message: "Use Layout { } function builder instead.") +// @available(*, deprecated, message: "Use Layout { } function builder instead.") @discardableResult func layout(_ objects: Any...) -> [UIView] { return layout(objects) From 433e69279416169863e5c47e577393de3fed87ca Mon Sep 17 00:00:00 2001 From: S4cha Date: Fri, 3 Apr 2020 18:22:00 +0200 Subject: [PATCH 09/12] Adds Hyphen bullet opperator --- Sources/Stevia/Stevia+DoubleDash.swift | 115 +++++++++++++++++++++++++ 1 file changed, 115 insertions(+) diff --git a/Sources/Stevia/Stevia+DoubleDash.swift b/Sources/Stevia/Stevia+DoubleDash.swift index 8d483e48..7180e998 100644 --- a/Sources/Stevia/Stevia+DoubleDash.swift +++ b/Sources/Stevia/Stevia+DoubleDash.swift @@ -138,3 +138,118 @@ public func -- (left: [UIView], right: SteviaRightFlexibleMargin) -> [UIView] { return left-right } #endif + +/// Hyphen Bullet operator is introduced to remove the ambiguity with the language "-" (minus) sign operator. +/// this ambiguity can make tu build times exponentially longer in big layout blocks. + + +#if canImport(UIKit) +import UIKit + +infix operator ⁃ :AdditionPrecedence + +@discardableResult +public func ⁃ (left: UIView, right: Double) -> PartialConstraint { + return left-right +} + +public func ⁃ (left: UIView, right: CGFloat) -> PartialConstraint { + return left⁃Double(right) +} + +public func ⁃ (left: UIView, right: Int) -> PartialConstraint { + return left⁃Double(right) +} + +@discardableResult +public func ⁃ (left: SideConstraint, right: UIView) -> UIView { + return left-right +} + +@discardableResult +public func ⁃ (left: [UIView], right: SideConstraint) -> [UIView] { + return left-right +} + +@discardableResult +public func ⁃ (left: UIView, right: SideConstraint) -> UIView { + return left-right +} + +@discardableResult +public func ⁃ (left: PartialConstraint, right: UIView) -> [UIView] { + return left-right +} + +@discardableResult +public func ⁃ (left: UIView, right: UIView) -> [UIView] { + return left-right +} + +@discardableResult +public func ⁃ (left: [UIView], right: Double) -> PartialConstraint { + return left-right +} + +@discardableResult +public func ⁃ (left: [UIView], right: CGFloat) -> PartialConstraint { + return left⁃Double(right) +} + +@discardableResult +public func ⁃ (left: [UIView], right: Int) -> PartialConstraint { + return left⁃Double(right) +} + +@discardableResult +public func ⁃ (left: [UIView], right: UIView) -> [UIView] { + return left-right +} + +@discardableResult +public func ⁃ (left: UIView, right: String) -> Space { + return left-right +} + +@discardableResult +public func ⁃ (left: [UIView], right: String) -> Space { + return left-right +} + +@discardableResult +public func ⁃ (left: Space, right: UIView) -> [UIView] { + return left-right +} + +@discardableResult +public func ⁃ (left: UIView, + right: SteviaFlexibleMargin) -> PartialFlexibleConstraint { + return left-right +} + +@discardableResult +public func ⁃ (left: [UIView], + right: SteviaFlexibleMargin) -> PartialFlexibleConstraint { + return left-right +} + +@discardableResult +public func ⁃ (left: PartialFlexibleConstraint, right: UIView) -> [UIView] { + return left-right +} + +@discardableResult +public func ⁃ (left: SteviaLeftFlexibleMargin, right: UIView) -> UIView { + return left-right +} + +@discardableResult +public func ⁃ (left: UIView, right: SteviaRightFlexibleMargin) -> UIView { + return left-right +} + +@discardableResult +public func ⁃ (left: [UIView], right: SteviaRightFlexibleMargin) -> [UIView] { + return left-right +} +#endif From 70a74394b002892c58d2700291953aedd14ba93a Mon Sep 17 00:00:00 2001 From: S4cha Date: Sat, 4 Apr 2020 11:31:17 +0200 Subject: [PATCH 10/12] Renames "sv" in subviews --- Sources/Stevia/Stevia+Hierarchy.swift | 85 ++++++++++++++++++++++----- 1 file changed, 71 insertions(+), 14 deletions(-) diff --git a/Sources/Stevia/Stevia+Hierarchy.swift b/Sources/Stevia/Stevia+Hierarchy.swift index 56281924..b2b296eb 100644 --- a/Sources/Stevia/Stevia+Hierarchy.swift +++ b/Sources/Stevia/Stevia+Hierarchy.swift @@ -17,6 +17,12 @@ import UIKit public extension UIView { + @available(*, deprecated, renamed: "subviews") + @discardableResult + func sv(_ subViews: UIView...) -> UIView { + subviews(subViews) + } + /** Defines the view hierachy for the view. @@ -35,7 +41,7 @@ public extension UIView { convenience init() { self.init(frame: CGRect.zero) - sv( + subviews( email, password, login @@ -49,10 +55,9 @@ public extension UIView { - Returns: Itself to enable nested layouts. */ -// @available(*, deprecated, message: "Use Subviews { } function builder instead.") @discardableResult - func sv(_ subViews: UIView...) -> UIView { - return sv(subViews) + func subviews(_ subViews: UIView...) -> UIView { + subviews(subViews) } /** @@ -88,10 +93,8 @@ public extension UIView { - Returns: Itself to enable nested layouts. */ @discardableResult - func Subviews(@SubviewsBuilder content: () -> [UIView]) -> UIView { - let subviews = content() - sv(subviews) - return self + func subviews(@SubviewsBuilder content: () -> [UIView]) -> UIView { + subviews(content()) } /** @@ -127,9 +130,9 @@ public extension UIView { - Returns: Itself to enable nested layouts. */ @discardableResult - func Subviews(@SubviewsBuilder content: () -> UIView) -> UIView { + func subviews(@SubviewsBuilder content: () -> UIView) -> UIView { let subview = content() - sv(subview) + subviews(subview) return self } @@ -164,7 +167,9 @@ public extension UIView { - Returns: Itself to enable nested layouts. */ - @objc @discardableResult + @available(*, deprecated, renamed: "subviews") + @objc + @discardableResult func sv(_ subViews: [UIView]) -> UIView { for sv in subViews { addSubview(sv) @@ -172,6 +177,16 @@ public extension UIView { } return self } + + + @objc @discardableResult + func subviews(_ subViews: [UIView]) -> UIView { + for sv in subViews { + addSubview(sv) + sv.translatesAutoresizingMaskIntoConstraints = false + } + return self + } } public extension UITableViewCell { @@ -206,9 +221,45 @@ public extension UITableViewCell { - Returns: Itself to enable nested layouts. */ + @available(*, deprecated, renamed: "subviews") @discardableResult override func sv(_ subViews: [UIView]) -> UIView { - return contentView.sv(subViews) + contentView.subviews(subViews) + } + + /** + Defines the view hierachy for the view. + + Esentially, this is just a shortcut to `contentView.addSubview` + and 'translatesAutoresizingMaskIntoConstraints = false' + + ``` + class NotificationCell: UITableViewCell { + + var avatar = UIImageView() + var name = UILabel() + var followButton = UIButton() + + required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } + override init(style: UITableViewCellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) { + + subviews( + avatar, + name, + followButton + ) + ... + + } + } + ``` + + - Returns: Itself to enable nested layouts. + */ + @discardableResult + override func subviews(_ subViews: [UIView]) -> UIView { + contentView.subviews(subViews) } } @@ -231,7 +282,7 @@ public extension UICollectionViewCell { override init(frame: CGRect) { super.init(frame: frame) - sv( + subviews( avatar, name, followButton @@ -244,9 +295,15 @@ public extension UICollectionViewCell { - Returns: Itself to enable nested layouts. */ + @available(*, deprecated, renamed: "subviews") @discardableResult override func sv(_ subViews: [UIView]) -> UIView { - return contentView.sv(subViews) + contentView.subviews(subViews) + } + + @discardableResult + override func subviews(_ subViews: [UIView]) -> UIView { + contentView.subviews(subViews) } } #endif From cf3383b6da05855155db822c41257a68c76382bb Mon Sep 17 00:00:00 2001 From: S4cha Date: Sun, 5 Apr 2020 11:23:52 +0200 Subject: [PATCH 11/12] Adds UIStackView "arrangedSubviews" --- Sources/Stevia/Stevia+Hierarchy.swift | 37 ++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/Sources/Stevia/Stevia+Hierarchy.swift b/Sources/Stevia/Stevia+Hierarchy.swift index b2b296eb..e5295642 100644 --- a/Sources/Stevia/Stevia+Hierarchy.swift +++ b/Sources/Stevia/Stevia+Hierarchy.swift @@ -167,19 +167,16 @@ public extension UIView { - Returns: Itself to enable nested layouts. */ - @available(*, deprecated, renamed: "subviews") @objc + @available(*, deprecated, renamed: "subviews") @discardableResult func sv(_ subViews: [UIView]) -> UIView { - for sv in subViews { - addSubview(sv) - sv.translatesAutoresizingMaskIntoConstraints = false - } - return self + subviews(subViews) } - @objc @discardableResult + @discardableResult + @objc func subviews(_ subViews: [UIView]) -> UIView { for sv in subViews { addSubview(sv) @@ -306,4 +303,30 @@ public extension UICollectionViewCell { contentView.subviews(subViews) } } + + +public extension UIStackView { + + @discardableResult + func arrangedSubviews(@SubviewsBuilder content: () -> [UIView]) -> UIView { + arrangedSubviews(content()) + } + + @discardableResult + func arrangedSubviews(@SubviewsBuilder content: () -> UIView) -> UIView { + arrangedSubviews([content()]) + } + + @discardableResult + private func arrangedSubviews(_ subViews: UIView...) -> UIView { + arrangedSubviews(subViews) + } + + @discardableResult + func arrangedSubviews(_ subViews: [UIView]) -> UIView { + subViews.forEach { addArrangedSubview($0) } + return self + } +} + #endif From 3d8cd72422c6ae6925227dbac35a4106e7cbbf94 Mon Sep 17 00:00:00 2001 From: S4cha Date: Sun, 5 Apr 2020 11:54:55 +0200 Subject: [PATCH 12/12] Updates tests --- .../LoginStevia/LoginViewNative.swift | 12 +- .../LoginStevia/LoginViewStevia.swift | 14 +- Sources/Stevia/Stevia+Hierarchy.swift | 4 +- Sources/Stevia/Stevia+Stacks.swift | 4 +- Tests/SteviaTests/BaselineTests.swift | 2 +- Tests/SteviaTests/CenterTests.swift | 2 +- Tests/SteviaTests/EquationTests.swift | 122 +++++++++--------- Tests/SteviaTests/FillTests.swift | 22 ++-- Tests/SteviaTests/FlexibleMarginTests.swift | 10 +- Tests/SteviaTests/FullLayoutTests.swift | 8 +- Tests/SteviaTests/GetConstraintsTests.swift | 2 +- Tests/SteviaTests/HierarchyTests.swift | 10 +- Tests/SteviaTests/LayoutTests.swift | 42 +++--- Tests/SteviaTests/PositionTests.swift | 2 +- Tests/SteviaTests/SizeTests.swift | 19 +-- 15 files changed, 136 insertions(+), 139 deletions(-) diff --git a/LoginExample/LoginStevia/LoginViewNative.swift b/LoginExample/LoginStevia/LoginViewNative.swift index 79fd676f..6580cfdd 100644 --- a/LoginExample/LoginStevia/LoginViewNative.swift +++ b/LoginExample/LoginStevia/LoginViewNative.swift @@ -16,12 +16,8 @@ class LoginViewNative: UIView { convenience init() { self.init(frame:CGRect.zero) - render() - } - - func render() { - // View Hieararchy + // 01 - View Hieararchy email.translatesAutoresizingMaskIntoConstraints = false password.translatesAutoresizingMaskIntoConstraints = false login.translatesAutoresizingMaskIntoConstraints = false @@ -29,7 +25,7 @@ class LoginViewNative: UIView { addSubview(password) addSubview(login) - // Layout (using latest layoutAnchors) + // 02 - Layout (using latest layoutAnchors) email.topAnchor.constraint(equalTo: topAnchor, constant: 100).isActive = true email.leftAnchor.constraint(equalTo: leftAnchor, constant: 8).isActive = true email.rightAnchor.constraint(equalTo: rightAnchor, constant: -8).isActive = true @@ -45,7 +41,7 @@ class LoginViewNative: UIView { login.rightAnchor.constraint(equalTo: rightAnchor).isActive = true login.heightAnchor.constraint(equalToConstant: 80).isActive = true - // Styling + // 03 - Styling backgroundColor = .gray email.borderStyle = .roundedRect email.autocorrectionType = .no @@ -58,7 +54,7 @@ class LoginViewNative: UIView { password.returnKeyType = .done login.backgroundColor = .lightGray - // Content + // 04 - Content email.placeholder = "Email" password.placeholder = "Password" login.setTitle("Login", for: .normal) diff --git a/LoginExample/LoginStevia/LoginViewStevia.swift b/LoginExample/LoginStevia/LoginViewStevia.swift index 70aaef23..53900c4c 100644 --- a/LoginExample/LoginStevia/LoginViewStevia.swift +++ b/LoginExample/LoginStevia/LoginViewStevia.swift @@ -19,19 +19,19 @@ class LoginViewStevia: UIView { self.init(frame:CGRect.zero) // Get injectionForXcode here : http://johnholdsworth.com/injection.html - // View Hierarchy + // 01 -View Hierarchy // This essentially does `translatesAutoresizingMaskIntoConstraints = false` // and `addSubsview()`. The neat benefit is that // (`Subviews` calls can be nested which will visually show hierarchy ! ) - Subviews { + subviews { email password login } - - // Vertical + Horizontal Layout in one pass + + // 02 - Vertical + Horizontal Layout in one pass // With type-safe visual format - Layout { + layout { 100 |-email-| ~ 80 8 @@ -70,7 +70,7 @@ class LoginViewStevia: UIView { // login.Height == 80 - // Styling 🎨 + // 03 - Styling 🎨 backgroundColor = .gray email.style(commonFieldStyle) password.style(commonFieldStyle).style { f in @@ -79,7 +79,7 @@ class LoginViewStevia: UIView { } login.backgroundColor = .lightGray - // Content 🖋 + // 04 - Content 🖋 email.placeholder = "Email" password.placeholder = "Password" login.setTitle("Login", for: .normal) diff --git a/Sources/Stevia/Stevia+Hierarchy.swift b/Sources/Stevia/Stevia+Hierarchy.swift index e5295642..ab9e8f40 100644 --- a/Sources/Stevia/Stevia+Hierarchy.swift +++ b/Sources/Stevia/Stevia+Hierarchy.swift @@ -78,7 +78,7 @@ public extension UIView { convenience init() { self.init(frame: CGRect.zero) - Subviews { + subviews { email password login @@ -115,7 +115,7 @@ public extension UIView { convenience init() { self.init(frame: CGRect.zero) - Subviews { + subviews { email password login diff --git a/Sources/Stevia/Stevia+Stacks.swift b/Sources/Stevia/Stevia+Stacks.swift index 91b4fda5..b817be81 100644 --- a/Sources/Stevia/Stevia+Stacks.swift +++ b/Sources/Stevia/Stevia+Stacks.swift @@ -40,16 +40,14 @@ public struct FlexibleSpace { public extension UIView { @discardableResult - func Layout(@SteviaLayoutBuilder content: () -> [SteviaLayoutItem]) -> UIView { + func layout(@SteviaLayoutBuilder content: () -> [SteviaLayoutItem]) -> UIView { let subviews = content() - let anys = subviews.map { $0.any } layout(anys) return self } } - #if canImport(UIKit) import UIKit diff --git a/Tests/SteviaTests/BaselineTests.swift b/Tests/SteviaTests/BaselineTests.swift index 5c6a5344..282a29ee 100644 --- a/Tests/SteviaTests/BaselineTests.swift +++ b/Tests/SteviaTests/BaselineTests.swift @@ -25,7 +25,7 @@ class BaselineTests: XCTestCase { label1 = UILabel() label2 = UILabel() - ctrler.view.Subviews { + ctrler.view.subviews { label1 label2 } diff --git a/Tests/SteviaTests/CenterTests.swift b/Tests/SteviaTests/CenterTests.swift index 9f673132..e0205795 100644 --- a/Tests/SteviaTests/CenterTests.swift +++ b/Tests/SteviaTests/CenterTests.swift @@ -22,7 +22,7 @@ class CenterTests: XCTestCase { ctrler = UIViewController() win.rootViewController = ctrler v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } // verify view h as default values XCTAssertEqual(v.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) diff --git a/Tests/SteviaTests/EquationTests.swift b/Tests/SteviaTests/EquationTests.swift index 991c411a..4c67fa67 100644 --- a/Tests/SteviaTests/EquationTests.swift +++ b/Tests/SteviaTests/EquationTests.swift @@ -27,7 +27,7 @@ class EquationTests: XCTestCase { func testTopDouble() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Top == ctrler.view.Top + Double(10) ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, 10) @@ -35,7 +35,7 @@ class EquationTests: XCTestCase { func testTopCGFloat() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Top == ctrler.view.Top + CGFloat(10) ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, 10) @@ -43,7 +43,7 @@ class EquationTests: XCTestCase { func testTopInt() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Top == ctrler.view.Top + Int(10) ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, 10) @@ -51,7 +51,7 @@ class EquationTests: XCTestCase { func testTopReflexive() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } ctrler.view.Top + 10 == v.Top ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, 10) @@ -59,7 +59,7 @@ class EquationTests: XCTestCase { func testTopGreaterOrEqual() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Top >= ctrler.view.Top + 10 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, 10) @@ -67,7 +67,7 @@ class EquationTests: XCTestCase { func testTopLessThanOrEqual() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Top <= ctrler.view.Top + 10 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, 10) @@ -75,7 +75,7 @@ class EquationTests: XCTestCase { func testBottomDouble() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Bottom == ctrler.view.Bottom - Double(23) ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, ctrler.view.frame.height - 23) @@ -83,7 +83,7 @@ class EquationTests: XCTestCase { func testBottomCGFloat() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Bottom == ctrler.view.Bottom - CGFloat(23) ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, ctrler.view.frame.height - 23) @@ -91,7 +91,7 @@ class EquationTests: XCTestCase { func testBottomInt() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Bottom == ctrler.view.Bottom - Int(23) ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, ctrler.view.frame.height - 23) @@ -99,7 +99,7 @@ class EquationTests: XCTestCase { func testBottomReflexive() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } ctrler.view.Bottom - 23 == v.Bottom ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, ctrler.view.frame.height - 23) @@ -107,7 +107,7 @@ class EquationTests: XCTestCase { func testBottomGreaterOrEqual() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Bottom >= ctrler.view.Bottom - 23 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, ctrler.view.frame.height - 23) @@ -115,7 +115,7 @@ class EquationTests: XCTestCase { func testBottomLessOrEqual() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Bottom <= ctrler.view.Bottom - 23 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, ctrler.view.frame.height - 23) @@ -123,7 +123,7 @@ class EquationTests: XCTestCase { func testLeft() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Left == ctrler.view.Left + 72 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.x, 72) @@ -131,7 +131,7 @@ class EquationTests: XCTestCase { func testLeftReflexive() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } ctrler.view.Left + 72 == v.Left ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.x, 72) @@ -139,7 +139,7 @@ class EquationTests: XCTestCase { func testLeftGreaterOrEqual() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Left >= ctrler.view.Left + 72 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.x, 72) @@ -147,7 +147,7 @@ class EquationTests: XCTestCase { func testLeftLessOrEqual() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Left <= ctrler.view.Left + 72 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.x, 72) @@ -155,7 +155,7 @@ class EquationTests: XCTestCase { func testRight() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Right == ctrler.view.Right - 13 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.x, ctrler.view.frame.width - 13) @@ -163,7 +163,7 @@ class EquationTests: XCTestCase { func testRightReflexive() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } ctrler.view.Right - 13 == v.Right ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.x, ctrler.view.frame.width - 13) @@ -171,7 +171,7 @@ class EquationTests: XCTestCase { func testRightGreaterOrEqual() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Right >= ctrler.view.Right - 13 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.x, ctrler.view.frame.width - 13) @@ -179,7 +179,7 @@ class EquationTests: XCTestCase { func testRightLessOrEqual() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Right >= ctrler.view.Right - 13 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.x, ctrler.view.frame.width - 13) @@ -187,7 +187,7 @@ class EquationTests: XCTestCase { func testWidth() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Width == ctrler.view.Width - 52 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.width, ctrler.view.frame.width - 52) @@ -195,7 +195,7 @@ class EquationTests: XCTestCase { func testWidthReflexive() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } ctrler.view.Width - 52 == v.Width ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.width, ctrler.view.frame.width - 52) @@ -203,7 +203,7 @@ class EquationTests: XCTestCase { func testWidthGreaterOrEqual() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Width >= ctrler.view.Width - 52 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.width, ctrler.view.frame.width - 52) @@ -211,7 +211,7 @@ class EquationTests: XCTestCase { func testWidthLessOrEqual() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Width <= ctrler.view.Width - 52 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.width, 0) @@ -219,7 +219,7 @@ class EquationTests: XCTestCase { func testHeight() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Height == ctrler.view.Height + 34 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.height, ctrler.view.frame.height + 34) @@ -227,7 +227,7 @@ class EquationTests: XCTestCase { func testHeightReflexive() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } ctrler.view.Height + 34 == v.Height ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.height, ctrler.view.frame.height + 34) @@ -235,7 +235,7 @@ class EquationTests: XCTestCase { func testHeightGreaterOrEqual() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Height >= ctrler.view.Height - 34 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.height, ctrler.view.frame.height - 34) @@ -243,7 +243,7 @@ class EquationTests: XCTestCase { func testHeightLessOrEqual() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Height <= ctrler.view.Height - 34 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.height, 0) @@ -253,7 +253,7 @@ class EquationTests: XCTestCase { func testSingleValueTopDouble() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Top == Double(10) ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, 10) @@ -261,7 +261,7 @@ class EquationTests: XCTestCase { func testSingleValueTopCGFloat() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Top == CGFloat(10) ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, 10) @@ -269,7 +269,7 @@ class EquationTests: XCTestCase { func testSingleValueTopInt() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Top == Int(10) ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, 10) @@ -277,7 +277,7 @@ class EquationTests: XCTestCase { func testSingleValueTopGreaterOrEqualDouble() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Top >= Double(10) ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, 10) @@ -285,7 +285,7 @@ class EquationTests: XCTestCase { func testSingleValueTopGreaterOrEqualCGFloat() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Top >= CGFloat(10) ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, 10) @@ -293,7 +293,7 @@ class EquationTests: XCTestCase { func testSingleValueTopGreaterOrEqualInt() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Top >= Int(10) ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, 10) @@ -301,7 +301,7 @@ class EquationTests: XCTestCase { func testSingleValueLessOrEqualDouble() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Top <= Double(10) ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, 10) @@ -309,7 +309,7 @@ class EquationTests: XCTestCase { func testSingleValueLessOrEqualCGFloat() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Top <= CGFloat(10) ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, 10) @@ -317,7 +317,7 @@ class EquationTests: XCTestCase { func testSingleValueLessOrEqualInt() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Top <= Int(10) ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, 10) @@ -325,7 +325,7 @@ class EquationTests: XCTestCase { func testSingleValueBottom() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Bottom == 23 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, ctrler.view.frame.height - 23) @@ -333,7 +333,7 @@ class EquationTests: XCTestCase { func testSingleValueBottomGreaterOrEqual() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Bottom >= 23 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, ctrler.view.frame.height - 23) @@ -341,7 +341,7 @@ class EquationTests: XCTestCase { func testSingleValueBottomLessOrEqual() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Bottom <= 23 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.y, ctrler.view.frame.height - 23) @@ -349,7 +349,7 @@ class EquationTests: XCTestCase { func testSingleValueLeft() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Left == 72 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.x, 72) @@ -357,7 +357,7 @@ class EquationTests: XCTestCase { func testSingleValueLeftGreaterOrEqual() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Left >= 72 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.x, 72) @@ -365,7 +365,7 @@ class EquationTests: XCTestCase { func testSingleValueLeftLessOrEqual() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Left <= 72 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.x, 72) @@ -373,7 +373,7 @@ class EquationTests: XCTestCase { func testSingleValueRight() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Right == 13 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.x, ctrler.view.frame.width - 13) @@ -381,7 +381,7 @@ class EquationTests: XCTestCase { func testSingleValueRightGreaterOrEqual() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Right >= 13 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.x, ctrler.view.frame.width - 13) @@ -389,7 +389,7 @@ class EquationTests: XCTestCase { func testSingleValueRightLessOrEqual() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Right <= 13 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.origin.x, ctrler.view.frame.width - 13) @@ -397,7 +397,7 @@ class EquationTests: XCTestCase { func testSingleValueWidth() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Width == 23 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.width, 23) @@ -405,7 +405,7 @@ class EquationTests: XCTestCase { func testSingleValueWidthGreaterOrEqual() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Width >= 23 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.width, 23) @@ -413,7 +413,7 @@ class EquationTests: XCTestCase { func testSingleValueWidthLessOrEqual() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.centerInContainer() // There is a bug where we need to have a x/y placement for size to be accurate. v.Width <= 23 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in @@ -422,7 +422,7 @@ class EquationTests: XCTestCase { func testSingleValueHeight() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Height == 94 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.height, 94) @@ -430,7 +430,7 @@ class EquationTests: XCTestCase { func testSingleValueHeightGreaterOrEqual() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.Height >= 94 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(v.frame.height, 94) @@ -438,7 +438,7 @@ class EquationTests: XCTestCase { func testSingleValueHeightLessOrEqual() { let v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.centerInContainer() // There is a bug where we need to have a x/y placement for size to be accurate. v.Height <= 94 ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in @@ -448,8 +448,8 @@ class EquationTests: XCTestCase { func testScrollView() { let scrollView = UIScrollView() let contentView = UIView() - ctrler.view.Subviews { - scrollView.Subviews { + ctrler.view.subviews { + scrollView.subviews { contentView } } @@ -462,8 +462,8 @@ class EquationTests: XCTestCase { func testScrollViewReflexive() { let scrollView = UIScrollView() let contentView = UIView() - ctrler.view.Subviews { - scrollView.Subviews { + ctrler.view.subviews { + scrollView.subviews { contentView } } @@ -479,8 +479,9 @@ class EquationTests: XCTestCase { let field = UIView() let dropdown = UIView() - ctrler.view.Subviews { - box.Subviews { + let aView: UIView = ctrler.view + aView.subviews { + box.subviews { field } dropdown @@ -507,8 +508,9 @@ class EquationTests: XCTestCase { let field = UIView() let dropdown = UIView() - ctrler.view.Subviews { - box.Subviews { + let aView: UIView = ctrler.view + aView.subviews { + box.subviews { field } dropdown diff --git a/Tests/SteviaTests/FillTests.swift b/Tests/SteviaTests/FillTests.swift index 55227c25..ad815411 100644 --- a/Tests/SteviaTests/FillTests.swift +++ b/Tests/SteviaTests/FillTests.swift @@ -27,7 +27,7 @@ class FillTests: XCTestCase { func testFillContainer() { let b = UIButton() - ctrler.view.Subviews { b } + ctrler.view.subviews { b } b.fillContainer() ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(ctrler.view.frame, b.frame) @@ -36,7 +36,7 @@ class FillTests: XCTestCase { func testFillContainerWithPaddingDouble() { let padding: Double = 10.0 let b = UIButton() - ctrler.view.Subviews { b } + ctrler.view.subviews { b } b.fillContainer(padding: padding) ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(ctrler.view.frame.height, b.frame.height + CGFloat(padding) * 2, @@ -48,7 +48,7 @@ class FillTests: XCTestCase { func testFillContainerWithPaddingCGFloat() { let padding: CGFloat = 10.0 let b = UIButton() - ctrler.view.Subviews { b } + ctrler.view.subviews { b } b.fillContainer(padding: padding) ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(ctrler.view.frame.height, b.frame.height + CGFloat(padding) * 2, @@ -60,7 +60,7 @@ class FillTests: XCTestCase { func testFillContainerWithPaddingInt() { let padding: Int = 10 let b = UIButton() - ctrler.view.Subviews { b } + ctrler.view.subviews { b } b.fillContainer(padding: padding) ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(ctrler.view.frame.height, b.frame.height + CGFloat(padding) * 2, @@ -71,7 +71,7 @@ class FillTests: XCTestCase { func testFillVertically() { let b = UIButton() - ctrler.view.Subviews { b } + ctrler.view.subviews { b } b.width(10) b.fillVertically() ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in @@ -82,7 +82,7 @@ class FillTests: XCTestCase { func testFillVerticallyWithPaddingDouble() { let padding: Double = 40.0 let b = UIButton() - ctrler.view.Subviews { b } + ctrler.view.subviews { b } b.fillVertically(padding: padding) ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(ctrler.view.frame.height, b.frame.height + CGFloat(padding) * 2, @@ -92,7 +92,7 @@ class FillTests: XCTestCase { func testFillVerticallyWithPaddingCGFloat() { let padding: CGFloat = 30.0 let b = UIButton() - ctrler.view.Subviews { b } + ctrler.view.subviews { b } b.fillVertically(padding: padding) ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(ctrler.view.frame.height, b.frame.height + CGFloat(padding) * 2, @@ -102,7 +102,7 @@ class FillTests: XCTestCase { func testFillVerticallyWithPaddingInt() { let padding: Int = 14 let b = UIButton() - ctrler.view.Subviews { b } + ctrler.view.subviews { b } b.fillVertically(padding: padding) ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(ctrler.view.frame.height, b.frame.height + CGFloat(padding) * 2, @@ -112,7 +112,7 @@ class FillTests: XCTestCase { func testFillHorizontallyWithPaddingDouble() { let padding: Double = 40.0 let b = UIButton() - ctrler.view.Subviews { b } + ctrler.view.subviews { b } b.fillHorizontally(padding: padding) ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(ctrler.view.frame.width, b.frame.width + CGFloat(padding) * 2, @@ -122,7 +122,7 @@ class FillTests: XCTestCase { func testFillHorizontallyWithPaddingCGFloat() { let padding: CGFloat = 30.0 let b = UIButton() - ctrler.view.Subviews { b } + ctrler.view.subviews { b } b.fillHorizontally(padding: padding) ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(ctrler.view.frame.width, b.frame.width + CGFloat(padding) * 2, @@ -132,7 +132,7 @@ class FillTests: XCTestCase { func testFillHorizontallyWithPaddingInt() { let padding: Int = 14 let b = UIButton() - ctrler.view.Subviews { b } + ctrler.view.subviews { b } b.fillHorizontally(padding: padding) ctrler.view.layoutIfNeeded() // This is needed to force auto-layout to kick-in XCTAssertEqual(ctrler.view.frame.width, b.frame.width + CGFloat(padding) * 2, diff --git a/Tests/SteviaTests/FlexibleMarginTests.swift b/Tests/SteviaTests/FlexibleMarginTests.swift index 97bd04db..b9251f88 100644 --- a/Tests/SteviaTests/FlexibleMarginTests.swift +++ b/Tests/SteviaTests/FlexibleMarginTests.swift @@ -21,7 +21,7 @@ class FlexibleMarginTests: XCTestCase { ctrler = UIViewController() win.rootViewController = ctrler v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } v.size(100.0) } @@ -266,7 +266,7 @@ class FlexibleMarginTests: XCTestCase { let v1 = UIView() let v2 = UIView() v.removeFromSuperview() - ctrler.view.Subviews { v1; v2 } + ctrler.view.subviews { v1; v2 } for view in ctrler.view.subviews { XCTAssertEqual(view.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(view.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) @@ -292,7 +292,7 @@ class FlexibleMarginTests: XCTestCase { let v1 = UIView() let v2 = UIView() v.removeFromSuperview() - ctrler.view.Subviews { + ctrler.view.subviews { v1 v2 } @@ -321,7 +321,7 @@ class FlexibleMarginTests: XCTestCase { let v1 = UIView() let v2 = UIView() v.removeFromSuperview() - ctrler.view.Subviews { + ctrler.view.subviews { v1 v2 } @@ -350,7 +350,7 @@ class FlexibleMarginTests: XCTestCase { let v1 = UIView() let v2 = UIView() v.removeFromSuperview() - ctrler.view.Subviews { + ctrler.view.subviews { v1 v2 } diff --git a/Tests/SteviaTests/FullLayoutTests.swift b/Tests/SteviaTests/FullLayoutTests.swift index 1066ae4f..356b698b 100644 --- a/Tests/SteviaTests/FullLayoutTests.swift +++ b/Tests/SteviaTests/FullLayoutTests.swift @@ -21,13 +21,13 @@ class TestView: UIView { convenience init() { self.init(frame: CGRect.zero) - Subviews { + subviews { email password login } - Layout { + layout { 100.5 |-email-22-| ~ 10% 20 @@ -37,12 +37,12 @@ class TestView: UIView { 7 } - Subviews { + subviews { view1 view2 } - Layout { + layout { 10% |view1| ~ 20 33% diff --git a/Tests/SteviaTests/GetConstraintsTests.swift b/Tests/SteviaTests/GetConstraintsTests.swift index 778f9fde..d6e369c0 100644 --- a/Tests/SteviaTests/GetConstraintsTests.swift +++ b/Tests/SteviaTests/GetConstraintsTests.swift @@ -17,7 +17,7 @@ class GetConstraintsTests: XCTestCase { override func setUp() { spv = UIView() v = UIView() - spv.Subviews { v } + spv.subviews { v } } func testCanGetLeftConstraint() { diff --git a/Tests/SteviaTests/HierarchyTests.swift b/Tests/SteviaTests/HierarchyTests.swift index 40317633..38fbd0fd 100644 --- a/Tests/SteviaTests/HierarchyTests.swift +++ b/Tests/SteviaTests/HierarchyTests.swift @@ -70,7 +70,7 @@ class HierarchyTests: XCTestCase { let view = UIView() let v1 = UIView() let v2 = UIView() - view.Subviews { + view.subviews { v1 v2 } @@ -85,7 +85,7 @@ class HierarchyTests: XCTestCase { let cell = UITableViewCell() let v1 = UIView() let v2 = UIView() - cell.Subviews { + cell.subviews { v1 v2 } @@ -102,7 +102,7 @@ class HierarchyTests: XCTestCase { let cell = UICollectionViewCell() let v1 = UIView() let v2 = UIView() - cell.Subviews { + cell.subviews { v1 v2 } @@ -119,8 +119,8 @@ class HierarchyTests: XCTestCase { let v2 = UIView() let v3 = UIView() let v4 = UIView() - view.Subviews { - v1.Subviews { + view.subviews { + v1.subviews { v3 v4 } diff --git a/Tests/SteviaTests/LayoutTests.swift b/Tests/SteviaTests/LayoutTests.swift index 433cc386..24783671 100644 --- a/Tests/SteviaTests/LayoutTests.swift +++ b/Tests/SteviaTests/LayoutTests.swift @@ -21,7 +21,7 @@ class LayoutTests: XCTestCase { ctrler = UIViewController() win.rootViewController = ctrler v = UIView() - ctrler.view.Subviews { v } + ctrler.view.subviews { v } verifyViewHasDefaultValues() } @@ -257,7 +257,7 @@ class LayoutTests: XCTestCase { let v2 = UIView() let v3 = UIView() v.removeFromSuperview() - ctrler.view.Subviews { + ctrler.view.subviews { v1 v2 v3 @@ -283,7 +283,7 @@ class LayoutTests: XCTestCase { let v2 = UIView() let v3 = UIView() v.removeFromSuperview() - ctrler.view.Subviews { + ctrler.view.subviews { v1 v2 v3 @@ -309,7 +309,7 @@ class LayoutTests: XCTestCase { let v2 = UIView() let v3 = UIView() v.removeFromSuperview() - ctrler.view.Subviews { + ctrler.view.subviews { v1 v2 v3 @@ -334,7 +334,7 @@ class LayoutTests: XCTestCase { let v1 = UIView() let v2 = UIView() v.removeFromSuperview() - ctrler.view.Subviews { + ctrler.view.subviews { v1 v2 } @@ -363,7 +363,7 @@ class LayoutTests: XCTestCase { let v1 = UIView() let v2 = UIView() v.removeFromSuperview() - ctrler.view.Subviews{ + ctrler.view.subviews { v1 v2 } @@ -391,7 +391,7 @@ class LayoutTests: XCTestCase { let v1 = UIView() let v2 = UIView() v.removeFromSuperview() - ctrler.view.Subviews { + ctrler.view.subviews { v1 v2 } @@ -419,7 +419,7 @@ class LayoutTests: XCTestCase { let v1 = UIView() let v2 = UIView() v.removeFromSuperview() - ctrler.view.Subviews { + ctrler.view.subviews { v1 v2 } @@ -448,7 +448,7 @@ class LayoutTests: XCTestCase { let v1 = UIView() let v2 = UIView() v.removeFromSuperview() - ctrler.view.Subviews { + ctrler.view.subviews { v1 v2 } @@ -478,7 +478,7 @@ class LayoutTests: XCTestCase { let v1 = UIView() let v2 = UIView() v.removeFromSuperview() - ctrler.view.Subviews { + ctrler.view.subviews { v1 v2 } @@ -505,7 +505,7 @@ class LayoutTests: XCTestCase { let v1 = UIView() let v2 = UIView() v.removeFromSuperview() - ctrler.view.Subviews { + ctrler.view.subviews { v1 v2 } @@ -539,7 +539,7 @@ class LayoutTests: XCTestCase { let v1 = UIView() let v2 = UIView() v.removeFromSuperview() - ctrler.view.Subviews { + ctrler.view.subviews { v1 v2 } @@ -570,7 +570,7 @@ class LayoutTests: XCTestCase { let v2 = UIView() let v3 = UIView() v.removeFromSuperview() - ctrler.view.Subviews { + ctrler.view.subviews { v1 v2 v3 @@ -583,7 +583,7 @@ class LayoutTests: XCTestCase { } - |v1.width(20)--v2.width(20)--v3 + |v1.width(20)⁃v2.width(20)⁃v3 ctrler.view.layoutIfNeeded() XCTAssertEqual(v1.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(v1.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) @@ -607,7 +607,7 @@ class LayoutTests: XCTestCase { let v2 = UIView() let v3 = UIView() v.removeFromSuperview() - ctrler.view.Subviews { + ctrler.view.subviews { v1 v2 v3 @@ -647,7 +647,7 @@ class LayoutTests: XCTestCase { let v2 = UIView() let v3 = UIView() v.removeFromSuperview() - ctrler.view.Subviews { + ctrler.view.subviews { v1 v2 v3 @@ -687,7 +687,7 @@ class LayoutTests: XCTestCase { let v2 = UIView() let v3 = UIView() v.removeFromSuperview() - ctrler.view.Subviews { + ctrler.view.subviews { v1 v2 v3 @@ -728,7 +728,7 @@ class LayoutTests: XCTestCase { let v2 = UIView() let v3 = UIView() v.removeFromSuperview() - ctrler.view.Subviews { + ctrler.view.subviews { v1 v2 v3 @@ -764,7 +764,7 @@ class LayoutTests: XCTestCase { let v1 = UIView() let v2 = UIView() v.removeFromSuperview() - ctrler.view.Subviews { + ctrler.view.subviews { v1 v2 } @@ -795,7 +795,7 @@ class LayoutTests: XCTestCase { let v1 = UIView() let v2 = UIView() v.removeFromSuperview() - ctrler.view.Subviews { + ctrler.view.subviews { v1 v2 } @@ -826,7 +826,7 @@ class LayoutTests: XCTestCase { let v2 = UIView() let v3 = UIView() v.removeFromSuperview() - ctrler.view.Subviews { v1; v2; v3 } + ctrler.view.subviews { v1; v2; v3 } for view in ctrler.view.subviews { XCTAssertEqual(view.frame.origin.y, 0, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(view.frame.origin.x, 0, accuracy: CGFloat(Float.ulpOfOne)) diff --git a/Tests/SteviaTests/PositionTests.swift b/Tests/SteviaTests/PositionTests.swift index 1edc12ee..0eb8fcc7 100644 --- a/Tests/SteviaTests/PositionTests.swift +++ b/Tests/SteviaTests/PositionTests.swift @@ -21,7 +21,7 @@ class PositionTests: XCTestCase { ctrler = UIViewController() win.rootViewController = ctrler v = UIView() - ctrler.view.Subviews {v } + ctrler.view.subviews {v } v.size(100.0) } diff --git a/Tests/SteviaTests/SizeTests.swift b/Tests/SteviaTests/SizeTests.swift index dc835cdd..c8cf226c 100644 --- a/Tests/SteviaTests/SizeTests.swift +++ b/Tests/SteviaTests/SizeTests.swift @@ -21,7 +21,7 @@ class SizeTests: XCTestCase { ctrler = UIViewController() win.rootViewController = ctrler v = UIView() - ctrler.view.Subviews { + ctrler.view.subviews { v } } @@ -112,7 +112,7 @@ class SizeTests: XCTestCase { let height = 267.0 let v1 = UIView() let v2 = UIView() - ctrler.view.Subviews { + ctrler.view.subviews { v1 v2 } @@ -129,7 +129,7 @@ class SizeTests: XCTestCase { let height = 267.0 let v1 = UIView() let v2 = UIView() - ctrler.view.Subviews { + ctrler.view.subviews { v1 v2 } @@ -144,14 +144,14 @@ class SizeTests: XCTestCase { func testFollwEdges() { let v1 = UIView() let v2 = UIView() - ctrler.view.Subviews { + ctrler.view.subviews { v1 v2 } let test = ctrler.view - test!.Layout { + test!.layout { 10 |-20-v1| ~ 32 } @@ -207,13 +207,14 @@ class SizeTests: XCTestCase { v.removeFromSuperview() v.height(80) v.width(80) - ctrler.view?.Subviews { v } + ctrler.view?.subviews { v } - let view = ctrler.view - view?.Layout { + let view: UIView = ctrler.view + view.layout { 0 - |v + |v! } + ctrler.view.layoutIfNeeded() XCTAssertEqual(v.frame.width, 80, accuracy: CGFloat(Float.ulpOfOne)) XCTAssertEqual(v.frame.height, 80, accuracy: CGFloat(Float.ulpOfOne))