Skip to content

Commit

Permalink
Complete width and height enhancements
Browse files Browse the repository at this point in the history
  • Loading branch information
Nikita Ermolenko committed Dec 28, 2017
1 parent 2ba927c commit 64d038b
Show file tree
Hide file tree
Showing 2 changed files with 197 additions and 23 deletions.
86 changes: 74 additions & 12 deletions Sources/Maker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -438,18 +438,37 @@ public final class Maker {
/// - returns: `Maker` instance for chaining relations.

@discardableResult public func heightToFit() -> Maker {
view.sizeToFit()
setHighPriorityValue(view.bounds.height, for: .height)
return self
return heightThatFits(maxHeight: CGFloat.greatestFiniteMagnitude)
}

/// Calculates the height that best fits the specified size.
///
/// - returns: `Maker` instance for chaining relations.

@discardableResult public func heightThatFits(height: Number) -> Maker {
view.sizeToFit()
setHighPriorityValue(min(view.bounds.height, height.value), for: .height)
@discardableResult public func heightThatFits(maxHeight: Number) -> Maker {
let handler = { [unowned self] in
let fitWidth: CGFloat

if let parameter = self.widthParameter {
fitWidth = parameter.value
}
else if let parameter = self.widthToParameter {
fitWidth = self.relationSize(view: parameter.view, for: parameter.relationType) * parameter.value
}
else if let leftParameter = self.leftParameter, let rightParameter = self.rightParameter {
let leftViewX = self.convertedValue(for: leftParameter.relationType, with: leftParameter.view) + leftParameter.value
let rightViewX = self.convertedValue(for: rightParameter.relationType, with: rightParameter.view) - rightParameter.value

fitWidth = rightViewX - leftViewX
}
else {
fitWidth = .greatestFiniteMagnitude
}

let fitSize = self.view.sizeThatFits(CGSize(width: fitWidth, height: .greatestFiniteMagnitude))
self.newRect.setValue(min(maxHeight.value, fitSize.height), for: .height)
}
handlers.append((.high, handler))
return self
}

Expand All @@ -458,18 +477,38 @@ public final class Maker {
/// - returns: `Maker` instance for chaining relations.

@discardableResult public func widthToFit() -> Maker {
view.sizeToFit()
setHighPriorityValue(view.bounds.width, for: .width)
return self
return widthThatFits(maxWidth: CGFloat.greatestFiniteMagnitude)
}

/// Calculates the width that best fits the specified size.
///
/// - returns: `Maker` instance for chaining relations.

@discardableResult public func widthThatFits(width: Number) -> Maker {
view.sizeToFit()
setHighPriorityValue(min(view.bounds.width, width.value), for: .width)
@discardableResult public func widthThatFits(maxWidth: Number) -> Maker {
let handler = { [unowned self] in
let fitHeight: CGFloat

if let parameter = self.heightParameter {
fitHeight = parameter.value
}
else if let parameter = self.heightToParameter {
fitHeight = self.relationSize(view: parameter.view, for: parameter.relationType) * parameter.value
}
else if let topParameter = self.topParameter, let bottomParameter = self.bottomParameter {
let topViewY = self.convertedValue(for: topParameter.relationType, with: topParameter.view) + topParameter.value
let bottomViewY = self.convertedValue(for: bottomParameter.relationType, with: bottomParameter.view) - bottomParameter.value

fitHeight = bottomViewY - topViewY
}
else {
fitHeight = .greatestFiniteMagnitude
}

let fitSize = self.view.sizeThatFits(CGSize(width: .greatestFiniteMagnitude, height: fitHeight))
self.newRect.setValue(min(maxWidth.value, fitSize.width), for: .width)
}

handlers.append((.high, handler))
return self
}

Expand Down Expand Up @@ -890,3 +929,26 @@ public final class Maker {
}
}
}

// MARK: - Deprecated

extension Maker {

/// Calculates the width that best fits the specified size.
///
/// - returns: `Maker` instance for chaining relations.

@available(*, unavailable, renamed: "widthThatFits(maxWidth:)")
@discardableResult public func widthThatFits(width: Number) -> Maker {
return self
}

/// Calculates the height that best fits the specified size.
///
/// - returns: `Maker` instance for chaining relations.

@available(*, unavailable, renamed: "heightThatFits(maxHeight:)")
@discardableResult public func heightThatFits(height: Number) -> Maker {
return self
}
}
134 changes: 123 additions & 11 deletions Tests/MakerWidthHeightTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,40 @@
import XCTest
@testable import Framezilla

final class HeightFitView: UIView {

let maxHeight: CGFloat = 100
let middleHeight: CGFloat = 70
let lowHeight: CGFloat = 50

override func sizeThatFits(_ size: CGSize) -> CGSize {
if size.width > 100 {
return CGSize(width: size.width, height: maxHeight)
}
else if size.width < 50 {
return CGSize(width: size.width, height: lowHeight)
}
return CGSize(width: size.width, height: middleHeight)
}
}

final class WidthFitView: UIView {

let maxWidth: CGFloat = 100
let middleWidth: CGFloat = 70
let lowWidth: CGFloat = 50

override func sizeThatFits(_ size: CGSize) -> CGSize {
if size.height > 100 {
return CGSize(width: maxWidth, height: size.height)
}
else if size.height < 50 {
return CGSize(width: lowWidth, height: size.width)
}
return CGSize(width: middleWidth, height: size.width)
}
}

class MakerWidthHeightTests: BaseTest {

func testThatJustSetting_width_configuresCorrectly() {
Expand Down Expand Up @@ -157,6 +191,57 @@ class MakerWidthHeightTests: BaseTest {

/* width / height to fit */

func testHeightToFit() {

let label = UILabel()
label.text = "HelloHelloHelloHello"

label.configureFrame { maker in
maker.heightToFit()
}
XCTAssertTrue(label.bounds.height > 0)
XCTAssertEqual(label.bounds.width, 0)
}

func testHeightToFit_withWidthRelation() {

let view = HeightFitView()

view.configureFrame { maker in
maker.heightToFit()
maker.width(120)
}
XCTAssertEqual(view.frame, CGRect(x: 0, y: 0, width: 120, height: view.maxHeight))
}

func testHeightToFit_withLeftAndRightRelations() {

let view = HeightFitView()
mainView.addSubview(view)

view.configureFrame { maker in
maker.heightToFit()
maker.left(inset: 220).right(inset: 220)
maker.top()
}
XCTAssertEqual(view.frame, CGRect(x: 220, y: 0, width: 60, height: view.middleHeight))
view.removeFromSuperview()
}

func testHeightToFit_withWidthToRelation() {

let view = HeightFitView()
mainView.addSubview(view)

view.configureFrame { maker in
maker.heightToFit()
maker.width(to: mainView.nui_width, multiplier: 0.01)
maker.top()
}
XCTAssertEqual(view.frame, CGRect(x: 0, y: 0, width: 5, height: view.lowHeight))
view.removeFromSuperview()
}

func testWidthToFit() {

let label = UILabel()
Expand All @@ -169,16 +254,43 @@ class MakerWidthHeightTests: BaseTest {
XCTAssertEqual(label.bounds.height, 0)
}

func testHeightToFit() {
func testWidthToFit_withHeightRelation() {

let label = UILabel()
label.text = "HelloHelloHelloHello"
let view = WidthFitView()

label.configureFrame { maker in
maker.heightToFit()
view.configureFrame { maker in
maker.widthToFit()
maker.height(120)
}
XCTAssertTrue(label.bounds.height > 0)
XCTAssertEqual(label.bounds.width, 0)
XCTAssertEqual(view.frame, CGRect(x: 0, y: 0, width: view.maxWidth, height: 120))
}

func testWidthToFit_withTopAndBottomRelations() {

let view = WidthFitView()
mainView.addSubview(view)

view.configureFrame { maker in
maker.widthToFit()
maker.top(inset: 220).bottom(inset: 220)
maker.left()
}
XCTAssertEqual(view.frame, CGRect(x: 0, y: 220, width: view.middleWidth, height: 60))
view.removeFromSuperview()
}

func testWidthToFit_withHeightToRelation() {

let view = WidthFitView()
mainView.addSubview(view)

view.configureFrame { maker in
maker.widthToFit()
maker.height(to: mainView.nui_width, multiplier: 0.01)
maker.left()
}
XCTAssertEqual(view.frame, CGRect(x: 0, y: 0, width: view.lowWidth, height: 5))
view.removeFromSuperview()
}

/* width / height that fits */
Expand All @@ -189,7 +301,7 @@ class MakerWidthHeightTests: BaseTest {
label.text = "HelloHelloHelloHello"

label.configureFrame { maker in
maker.widthThatFits(width: 30)
maker.widthThatFits(maxWidth: 30)
}
XCTAssertEqual(label.bounds.width, 30)
XCTAssertEqual(label.bounds.height, 0)
Expand All @@ -201,7 +313,7 @@ class MakerWidthHeightTests: BaseTest {
label.text = "HelloHelloHelloHello"

label.configureFrame { maker in
maker.widthThatFits(width: 300)
maker.widthThatFits(maxWidth: 300)
}
XCTAssertTrue(label.bounds.width != 300)
XCTAssertEqual(label.bounds.height, 0)
Expand All @@ -213,7 +325,7 @@ class MakerWidthHeightTests: BaseTest {
label.text = "HelloHelloHelloHello"

label.configureFrame { maker in
maker.heightThatFits(height: 5)
maker.heightThatFits(maxHeight: 5)
}
XCTAssertEqual(label.bounds.height, 5)
XCTAssertEqual(label.bounds.width, 0)
Expand All @@ -225,7 +337,7 @@ class MakerWidthHeightTests: BaseTest {
label.text = "HelloHelloHelloHello"

label.configureFrame { maker in
maker.heightThatFits(height: 300)
maker.heightThatFits(maxHeight: 300)
}
XCTAssertTrue(label.bounds.height != 300)
XCTAssertEqual(label.bounds.width, 0)
Expand Down

0 comments on commit 64d038b

Please sign in to comment.