From c26f15f765e0946e1391eeaa7de75d73c836f62d Mon Sep 17 00:00:00 2001 From: Nikita Ermolenko Date: Tue, 27 Feb 2018 16:51:39 +0600 Subject: [PATCH 1/4] Fix container's width and height when it's configured with specific relations even if subviews have a larger size --- Sources/UIView+Installer.swift | 27 ++++++++++++++-- Tests/ContainerTests.swift | 56 ++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 3 deletions(-) diff --git a/Sources/UIView+Installer.swift b/Sources/UIView+Installer.swift index 383e90a..c87c510 100644 --- a/Sources/UIView+Installer.swift +++ b/Sources/UIView+Installer.swift @@ -143,10 +143,19 @@ public extension Collection where Iterator.Element: UIView, Self.Index == Int, S public func configure(container: UIView, relation: ContainerRelation? = nil, installerBlock: () -> Void) { container.frame = .zero + var relationWidth: CGFloat? + var relationHeight: CGFloat? + if let relation = relation { switch relation { - case let .width(width): container.frame.size.width = width.value - case let .height(height): container.frame.size.height = height.value + case let .width(width): + container.frame.size.width = width.value + relationWidth = width.value + + case let .height(height): + container.frame.size.height = height.value + relationHeight = height.value + case let .horizontal(lInset, rInset): container.configureFrame { maker in maker.left(inset: lInset).right(inset: rInset) @@ -154,6 +163,8 @@ public extension Collection where Iterator.Element: UIView, Self.Index == Int, S let width = container.frame.width container.frame = .zero container.frame.size.width = width + relationWidth = width + case let .vertical(tInset, bInset): container.configureFrame { maker in maker.top(inset: tInset).bottom(inset: bInset) @@ -161,10 +172,11 @@ public extension Collection where Iterator.Element: UIView, Self.Index == Int, S let height = container.frame.height container.frame = .zero container.frame.size.height = height + relationHeight = height } } - for subview in self { + for subview in self where subview.superview != container { container.addSubview(subview) } @@ -172,6 +184,15 @@ public extension Collection where Iterator.Element: UIView, Self.Index == Int, S container.configureFrame { maker in maker.container() } + + if let width = relationWidth { + container.frame.size.width = width + } + + if let height = relationHeight { + container.frame.size.height = height + } + installerBlock() } diff --git a/Tests/ContainerTests.swift b/Tests/ContainerTests.swift index 0916a2d..382192b 100644 --- a/Tests/ContainerTests.swift +++ b/Tests/ContainerTests.swift @@ -272,4 +272,60 @@ class ContainerTests: BaseTest { XCTAssertEqual(content3.frame, CGRect(x: 140, y: 0, width: 70, height: 200)) XCTAssertEqual(content4.frame, CGRect(x: 230, y: 85, width: 30, height: 30)) } + + func testContainerHaveConstantWidthWithLeftAndRightRelations() { + let content1 = UIView() + + let container = [content1].container(in: mainView, relation: .horizontal(left: 50, right: 50)) { + content1.configureFrame { maker in + maker.top() + maker.size(width: 500, height: 100) + } + } + + XCTAssertEqual(container.frame, CGRect(x: 0, y: 0, width: 400, height: 100)) + XCTAssertEqual(content1.frame, CGRect(x: 0, y: 0, width: 500, height: 100)) + } + + func testContainerHaveConstantWidthWithWidthRelation() { + let content1 = UIView() + + let container = [content1].container(in: mainView, relation: .width(400)) { + content1.configureFrame { maker in + maker.top() + maker.size(width: 500, height: 100) + } + } + + XCTAssertEqual(container.frame, CGRect(x: 0, y: 0, width: 400, height: 100)) + XCTAssertEqual(content1.frame, CGRect(x: 0, y: 0, width: 500, height: 100)) + } + + func testContainerHaveConstantHeightWithTopAndBottomRelations() { + let content1 = UIView() + + let container = [content1].container(in: mainView, relation: .vertical(top: 50, bottom: 50)) { + content1.configureFrame { maker in + maker.top() + maker.size(width: 100, height: 500) + } + } + + XCTAssertEqual(container.frame, CGRect(x: 0, y: 0, width: 100, height: 400)) + XCTAssertEqual(content1.frame, CGRect(x: 0, y: 0, width: 100, height: 500)) + } + + func testContainerHaveConstantHeightWithHeightRelation() { + let content1 = UIView() + + let container = [content1].container(in: mainView, relation: .height(400)) { + content1.configureFrame { maker in + maker.top() + maker.size(width: 100, height: 500) + } + } + + XCTAssertEqual(container.frame, CGRect(x: 0, y: 0, width: 100, height: 400)) + XCTAssertEqual(content1.frame, CGRect(x: 0, y: 0, width: 100, height: 500)) + } } From 54a702a0fabc0f5bd6b9fe5f112b9148a6c0c35c Mon Sep 17 00:00:00 2001 From: Nikita Ermolenko Date: Tue, 27 Feb 2018 17:16:52 +0600 Subject: [PATCH 2/4] Add a deprecated message to the old `container` method --- Sources/Maker.swift | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/Sources/Maker.swift b/Sources/Maker.swift index 539b3d9..e1cb7d3 100644 --- a/Sources/Maker.swift +++ b/Sources/Maker.swift @@ -382,21 +382,26 @@ public final class Maker { /// /// - returns: `Maker` instance for chaining relations. + @available(*, deprecated, message: "there is a more flexible container method - сheck the method description.") @discardableResult public func container() -> Maker { + return _container() + } + + @discardableResult func _container() -> Maker { var frame = CGRect.zero - + var minX: CGFloat = 0 var minY: CGFloat = 0 - + for subview in view.subviews { if subview.frame.origin.x < 0 { subview.frame.origin.x = 0 } - + if subview.frame.origin.y < 0 { subview.frame.origin.y = 0 } - + if subview.frame.origin.x < minX { minX = subview.frame.origin.x } @@ -404,14 +409,14 @@ public final class Maker { minY = subview.frame.origin.y } } - + for subview in view.subviews { subview.frame.origin.x -= minX subview.frame.origin.y -= minY - + frame = frame.union(subview.frame) } - + setHighPriorityValue(frame.width, for: .width) setHighPriorityValue(frame.height, for: .height) return self From ece1d8acd4b405e29328c7401a008b6e8cf4f607 Mon Sep 17 00:00:00 2001 From: Nikita Ermolenko Date: Tue, 27 Feb 2018 17:21:07 +0600 Subject: [PATCH 3/4] A bit refactoring --- Framezilla.xcodeproj/project.pbxproj | 4 ++++ Sources/Maker+Unavailable.swift | 29 ++++++++++++++++++++++++++++ Sources/Maker.swift | 23 ---------------------- Sources/UIView+Installer.swift | 4 ++-- Tests/MakerTests.swift | 2 +- 5 files changed, 36 insertions(+), 26 deletions(-) create mode 100644 Sources/Maker+Unavailable.swift diff --git a/Framezilla.xcodeproj/project.pbxproj b/Framezilla.xcodeproj/project.pbxproj index 70690be..c4b1cb3 100644 --- a/Framezilla.xcodeproj/project.pbxproj +++ b/Framezilla.xcodeproj/project.pbxproj @@ -23,6 +23,7 @@ 8442F9431EC75A8500B72551 /* MakerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8442F93B1EC75A8500B72551 /* MakerTests.swift */; }; 8442F9441EC75A8500B72551 /* MakerWidthHeightTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8442F93C1EC75A8500B72551 /* MakerWidthHeightTests.swift */; }; 8442F9451EC75A8500B72551 /* StateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8442F93D1EC75A8500B72551 /* StateTests.swift */; }; + 844BE8F320457634004C19A8 /* Maker+Unavailable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 844BE8F220457634004C19A8 /* Maker+Unavailable.swift */; }; 845108071EE2F5BC006DC1C8 /* ScrollViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845108061EE2F5BC006DC1C8 /* ScrollViewTests.swift */; }; 8497C0111E59EB7700447E2F /* Number.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8497C0101E59EB7700447E2F /* Number.swift */; }; 8497C0131E59FA4B00447E2F /* Array+Stack.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8497C0121E59FA4B00447E2F /* Array+Stack.swift */; }; @@ -63,6 +64,7 @@ 8442F93B1EC75A8500B72551 /* MakerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MakerTests.swift; sourceTree = ""; }; 8442F93C1EC75A8500B72551 /* MakerWidthHeightTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MakerWidthHeightTests.swift; sourceTree = ""; }; 8442F93D1EC75A8500B72551 /* StateTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StateTests.swift; sourceTree = ""; }; + 844BE8F220457634004C19A8 /* Maker+Unavailable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Maker+Unavailable.swift"; sourceTree = ""; }; 845108061EE2F5BC006DC1C8 /* ScrollViewTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScrollViewTests.swift; sourceTree = ""; }; 8497C0101E59EB7700447E2F /* Number.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Number.swift; sourceTree = ""; }; 8497C0121E59FA4B00447E2F /* Array+Stack.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Array+Stack.swift"; sourceTree = ""; }; @@ -122,6 +124,7 @@ 8497C0101E59EB7700447E2F /* Number.swift */, 8497C0121E59FA4B00447E2F /* Array+Stack.swift */, 842BB7FB1F0638E9000D1CFF /* Parameters.swift */, + 844BE8F220457634004C19A8 /* Maker+Unavailable.swift */, ); path = Sources; sourceTree = ""; @@ -297,6 +300,7 @@ 11FB41471D844F8F00700A40 /* MakerHelper.swift in Sources */, 8497C0131E59FA4B00447E2F /* Array+Stack.swift in Sources */, 11FB41481D844F8F00700A40 /* UIView+Installer.swift in Sources */, + 844BE8F320457634004C19A8 /* Maker+Unavailable.swift in Sources */, 11FB41491D844F8F00700A40 /* UIView+Relations.swift in Sources */, 842BB7FC1F0638E9000D1CFF /* Parameters.swift in Sources */, ); diff --git a/Sources/Maker+Unavailable.swift b/Sources/Maker+Unavailable.swift new file mode 100644 index 0000000..6e82057 --- /dev/null +++ b/Sources/Maker+Unavailable.swift @@ -0,0 +1,29 @@ +// +// Maker+Unavailable.swift +// Framezilla iOS +// +// Created by Nikita Ermolenko on 27/02/2018. +// + +import Foundation + +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 + } +} diff --git a/Sources/Maker.swift b/Sources/Maker.swift index e1cb7d3..79dcb17 100644 --- a/Sources/Maker.swift +++ b/Sources/Maker.swift @@ -976,26 +976,3 @@ 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 - } -} diff --git a/Sources/UIView+Installer.swift b/Sources/UIView+Installer.swift index c87c510..dd16c9e 100644 --- a/Sources/UIView+Installer.swift +++ b/Sources/UIView+Installer.swift @@ -122,7 +122,7 @@ public enum ContainerRelation { case vertical(top: Number, bottom: Number) } -public extension Collection where Iterator.Element: UIView, Self.Index == Int, Self.IndexDistance == Int { +public extension Collection where Iterator.Element: UIView { /// Configures all subview within a passed container. /// @@ -182,7 +182,7 @@ public extension Collection where Iterator.Element: UIView, Self.Index == Int, S installerBlock() container.configureFrame { maker in - maker.container() + maker._container() } if let width = relationWidth { diff --git a/Tests/MakerTests.swift b/Tests/MakerTests.swift index d9d7719..95a3368 100644 --- a/Tests/MakerTests.swift +++ b/Tests/MakerTests.swift @@ -382,7 +382,7 @@ class MakerTests: BaseTest { containet.addSubview(view2) containet.configureFrame { maker in - maker.container() + maker._container() } XCTAssertEqual(containet.frame, CGRect(x: 0, y: 0, width: 120, height: 120)) } From 3df85dcc991980b10a62a7092926e39a5608c739 Mon Sep 17 00:00:00 2001 From: Nikita Ermolenko Date: Wed, 28 Feb 2018 09:06:29 +0600 Subject: [PATCH 4/4] Change the podspec version -> 2.9.1 --- Framezilla.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Framezilla.podspec b/Framezilla.podspec index 7a66bd0..b61f34e 100644 --- a/Framezilla.podspec +++ b/Framezilla.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |spec| spec.name = "Framezilla" - spec.version = "2.9.0" + spec.version = "2.9.1" spec.summary = "Comfortable syntax for working with frames." spec.homepage = "https://github.com/Otbivnoe/Framezilla"