Skip to content
This repository has been archived by the owner on Sep 21, 2021. It is now read-only.

Commit

Permalink
Merge branch 'release/2.8.0'
Browse files Browse the repository at this point in the history
# Conflicts:
#	Framezilla.podspec
  • Loading branch information
Nikita Ermolenko committed Feb 2, 2018
2 parents 1c83909 + e9a9627 commit 52c9f5a
Show file tree
Hide file tree
Showing 8 changed files with 424 additions and 168 deletions.
101 changes: 38 additions & 63 deletions Example/FramezillaExample/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,98 +11,73 @@ import Framezilla

class ViewController: UIViewController {

let container = UIView()

let content1 = UIView()
let content2 = UIView()
let content3 = UIView()
let content4 = UIView()

let label1 = UILabel()
let label2 = UILabel()
let label3 = UILabel()

override func viewDidLoad() {
super.viewDidLoad()

view.backgroundColor = .white

container.backgroundColor = .yellow

content1.backgroundColor = .red
content2.backgroundColor = .black
content3.backgroundColor = .green
content4.backgroundColor = .gray

label1.backgroundColor = .red
label2.backgroundColor = .green
label3.backgroundColor = .gray

label1.numberOfLines = 0
label2.numberOfLines = 0
label3.numberOfLines = 0

label1.text = "Helloe Helloe Helloe Helloe Helloe Helloe Helloe Helloe Helloe Helloe Helloe"
label2.text = "Helloe Helloe Helloe Helloe Helloe"
label3.text = "Helloe"

view.addSubview(container)
}

override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()

// let container = [content1, content2, content3, content4].container(in: view) {
// content1.configureFrame { maker in
// maker.centerX()
// maker.top()
// maker.size(width: 50, height: 50)
// }
//
// content2.configureFrame { maker in
// maker.top(to: content1.nui_bottom, inset: 5)
// maker.left()
// maker.size(width: 80, height: 80)
// }
//
// content3.configureFrame { maker in
// maker.top(to: content1.nui_bottom, inset: 15)
// maker.left(to: content2.nui_right, inset: 5)
// maker.size(width: 80, height: 80)
// }
//
// content4.configureFrame { maker in
// maker.top(to: content3.nui_bottom, inset: 5)
// maker.right()
// maker.size(width: 20, height: 20)
// }
// }



let container = [content1, content2, content3].container(in: view) {
[content1, label1, label2, label3].configure(container: container, relation: .horizontal(left: 20, right: 20)) {
content1.configureFrame { maker in
maker.right()
maker.centerY()
maker.size(width: 50, height: 50)
maker.top(inset: 10)
maker.size(width: 100, height: 60)
maker.centerX()
}

content2.configureFrame { maker in
maker.right(to: content1.nui_left, inset: 5)
maker.centerY()
maker.size(width: 30, height: 140)
label1.configureFrame { maker in
maker.left().right().top(to: content1.nui_bottom, inset: 10)
maker.heightToFit()
}

content3.configureFrame { maker in
maker.right(to: content2.nui_left, inset: 15)
maker.centerY()
maker.size(width: 80, height: 80)
label2.configureFrame { maker in
maker.left().right().top(to: label1.nui_bottom, inset: 10)
maker.heightToFit()
}
}


// let container = [content1, content2, content3].container(in: view) {
// content1.configureFrame { maker in
// maker.bottom()
// maker.centerX()
// maker.size(width: 50, height: 50)
// }
//
// content2.configureFrame { maker in
// maker.bottom(to: content1.nui_top, inset: 5)
// maker.centerX()
// maker.size(width: 30, height: 140)
// }
//
// content3.configureFrame { maker in
// maker.left()
// maker.bottom(to: content2.nui_top, inset: 15)
// maker.size(width: 10, height: 10)
// }
// }
label3.configureFrame { maker in
maker.left().right().top(to: label2.nui_bottom, inset: 20)
maker.heightToFit()
}
}

container.backgroundColor = .yellow
container.configureFrame { maker in
maker.centerX()
maker.top()
maker.bottom(inset: 20)
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion Framezilla.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |spec|
spec.name = "Framezilla"
spec.version = "2.7.0"
spec.version = "2.8.0"
spec.summary = "Comfortable syntax for working with frames."

spec.homepage = "https://github.com/Otbivnoe/Framezilla"
Expand Down
8 changes: 4 additions & 4 deletions Framezilla.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
11FB41471D844F8F00700A40 /* MakerHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11FB41421D844F8F00700A40 /* MakerHelper.swift */; };
11FB41481D844F8F00700A40 /* UIView+Installer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11FB41431D844F8F00700A40 /* UIView+Installer.swift */; };
11FB41491D844F8F00700A40 /* UIView+Relations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11FB41441D844F8F00700A40 /* UIView+Relations.swift */; };
841192DD1FF205DC00AB255D /* ContainerInstallerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 841192DC1FF205DC00AB255D /* ContainerInstallerTests.swift */; };
841192DD1FF205DC00AB255D /* ContainerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 841192DC1FF205DC00AB255D /* ContainerTests.swift */; };
842BB7FC1F0638E9000D1CFF /* Parameters.swift in Sources */ = {isa = PBXBuildFile; fileRef = 842BB7FB1F0638E9000D1CFF /* Parameters.swift */; };
8442F93E1EC75A8500B72551 /* BaseTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8442F9351EC75A8500B72551 /* BaseTest.swift */; };
8442F9401EC75A8500B72551 /* MakerBothSideRelationsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8442F9381EC75A8500B72551 /* MakerBothSideRelationsTests.swift */; };
Expand Down Expand Up @@ -52,7 +52,7 @@
11FB414A1D844FFA00700A40 /* Framezilla.podspec */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Framezilla.podspec; sourceTree = "<group>"; };
11FB414B1D844FFA00700A40 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; };
11FB414C1D844FFA00700A40 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
841192DC1FF205DC00AB255D /* ContainerInstallerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContainerInstallerTests.swift; sourceTree = "<group>"; };
841192DC1FF205DC00AB255D /* ContainerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContainerTests.swift; sourceTree = "<group>"; };
842BB7FB1F0638E9000D1CFF /* Parameters.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Parameters.swift; sourceTree = "<group>"; };
8442F9351EC75A8500B72551 /* BaseTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseTest.swift; sourceTree = "<group>"; };
8442F9361EC75A8500B72551 /* FramezillaTests-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FramezillaTests-Bridging-Header.h"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -140,7 +140,7 @@
84EDCC231F9B3AB10091FAB9 /* MakerSafeAreaTests.swift */,
8442F93D1EC75A8500B72551 /* StateTests.swift */,
845108061EE2F5BC006DC1C8 /* ScrollViewTests.swift */,
841192DC1FF205DC00AB255D /* ContainerInstallerTests.swift */,
841192DC1FF205DC00AB255D /* ContainerTests.swift */,
);
path = Tests;
sourceTree = "<group>";
Expand Down Expand Up @@ -276,7 +276,7 @@
files = (
8442F9441EC75A8500B72551 /* MakerWidthHeightTests.swift in Sources */,
8442F9451EC75A8500B72551 /* StateTests.swift in Sources */,
841192DD1FF205DC00AB255D /* ContainerInstallerTests.swift in Sources */,
841192DD1FF205DC00AB255D /* ContainerTests.swift in Sources */,
8442F9411EC75A8500B72551 /* MakerCenterTests.swift in Sources */,
8442F9421EC75A8500B72551 /* MakerStackTests.swift in Sources */,
8442F9401EC75A8500B72551 /* MakerBothSideRelationsTests.swift in Sources */,
Expand Down
27 changes: 24 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,18 +222,31 @@ label.configureFrame { maker in

## Container

Use this method when you want to set `width` and `height` by wrapping all subviews.
Use this method when you want to calculate a `width` and `height` by wrapping all subviews.

You can also specify a special container relation:

```swift
public enum ContainerRelation {
case width(Number)
case height(Number)
case horizontal(left: Number, right: Number)
case vertical(top: Number, bottom: Number)
}
```

For instance, if you set a width for a container, only a dynamic height will be calculated.

### NOTE:

**It atomatically adds all subviews to the container. Don't add subviews manually.**

**Also important to understand, that it's not correct to call 'left' and 'right' relations together by subview, because `container` sets width relatively width of subview and here is some ambiguous.**
**If you don't use a static width for instance, important to understand, that it's not correct to call `left` and `right` relations together by subviews, because `container` sets width relatively width of subviews and here is some ambiguous.**

![](img/container.png)

```swift
let container = [content1, content2, content3, content4].container(in: view) {
let container = [content1, content2, content3, content4].container(in: view, relation: /* if needed */) {
content1.configureFrame { maker in
maker.centerX()
maker.top()
Expand Down Expand Up @@ -265,6 +278,14 @@ container.configureFrame { maker in
}
```

If you have already configured container, then this method will be more convenient for you:

```swift
[content1, label1, label2, label3].configure(container: container, relation: .horizontal(left: 20, right: 20)) {
// do configuration
}
```

## Cool things:

Sometimes you want to configure a few views with the same size, for examlple. There is a convinience method:
Expand Down
10 changes: 9 additions & 1 deletion Sources/Maker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,14 @@ public final class Maker {
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
}
Expand Down Expand Up @@ -662,7 +670,7 @@ public final class Maker {
/// Use this method when you want to join right side of current view with some horizontal side of another view.
///
/// - note: You can not use this method with other relations except for `nui_left`, `nui_centerX` and `nui_right`.
//
///
/// - parameter relationView: The view on which you set right relation.
/// - parameter inset: The inset for additional space between views. Default value: 0.
///
Expand Down
90 changes: 73 additions & 17 deletions Sources/UIView+Installer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -115,39 +115,95 @@ public extension Sequence where Iterator.Element: UIView {
}
}

public enum ContainerRelation {
case width(Number)
case height(Number)
case horizontal(left: Number, right: Number)
case vertical(top: Number, bottom: Number)
}

public extension Collection where Iterator.Element: UIView, Self.Index == Int, Self.IndexDistance == Int {

/// Creates сontainer view and configures all subview within this container.
/// Configures all subview within a passed container.
///
/// Use this method when you want to set `width` and `height` by wrapping all subviews.
/// Use this method when you want to calculate width and height by wrapping all subviews. Or use static parameters.
///
/// - note: It atomatically adds all subviews to the container. Don't add subviews manually.
/// - note: Also important to understand, that it's not correct to call 'left' and 'right' relations together by subview, because
/// `container` sets width relatively width of subview and here is some ambiguous.
/// - note: It automatically adds all subviews to the container. Don't add subviews manually.
/// - note: If you don't use a static width for instance, important to understand, that it's not correct to call 'left' and 'right' relations together by subviews,
/// because `container` sets width relatively width of subviews and here is some ambiguous.
///
/// - parameter view: The view where a container will be added.
/// - parameter installerBlock: The installer block within which you should configure frames for all subviews.
/// - parameter view: The view where a container will be added.
/// - parameter relation: The relation of `ContainerRelation` type.
/// - `width`: The width of a container. If you specify a width only a dynamic height will be calculated.
/// - `height`: The height of a container. If you specify a height only a dynamic width will be calculated.
/// - `horizontal(left, right)`: The left and right insets of a container. If you specify these parameters only a dynamic height will be calculated.
/// - `vertical(top, bottom)`: The top and bototm insets of a container. If you specify these parameters only a dynamic width will be calculated.
/// - parameter installerBlock: The installer block within which you should configure frames for all subviews.

public func configure(container: UIView, relation: ContainerRelation? = nil, installerBlock: () -> Void) {
container.frame = .zero

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 .horizontal(lInset, rInset):
container.configureFrame { maker in
maker.left(inset: lInset).right(inset: rInset)
}
let width = container.frame.width
container.frame = .zero
container.frame.size.width = width
case let .vertical(tInset, bInset):
container.configureFrame { maker in
maker.top(inset: tInset).bottom(inset: bInset)
}
let height = container.frame.height
container.frame = .zero
container.frame.size.height = height
}
}

for subview in self {
container.addSubview(subview)
}

installerBlock()
container.configureFrame { maker in
maker.container()
}
installerBlock()
}

/// Creates a сontainer view and configures all subview within this container.
///
/// Use this method when you want to calculate `width` and `height` by wrapping all subviews. Or use static parameters.
///
/// - note: It automatically adds all subviews to the container. Don't add subviews manually. A generated container is automatically added to a `view` as well.
/// - note: If you don't use a static width for instance, important to understand, that it's not correct to call 'left' and 'right' relations together by subviews,
/// because `container` sets width relatively width of subviews and here is some ambiguous.
///
/// - parameter view: The view where a container will be added.
/// - parameter relation: The relation of `ContainerRelation` type.
/// - `width`: The width of a container. If you specify a width only a dynamic height will be calculated.
/// - `height`: The height of a container. If you specify a height only a dynamic width will be calculated.
/// - `horizontal(left, right)`: The left and right insets of a container. If you specify these parameters only a dynamic height will be calculated.
/// - `vertical(top, bottom)`: The top and bototm insets of a container. If you specify these parameters only a dynamic width will be calculated.
/// - parameter installerBlock: The installer block within which you should configure frames for all subviews.
///
/// - returns: Container view.

public func container(in view: UIView, installerBlock: () -> Void) -> UIView {
public func container(in view: UIView, relation: ContainerRelation? = nil, installerBlock: () -> Void) -> UIView {
let container: UIView
if let superView = self.first?.superview {
container = superView
}
else {
container = UIView()
}
for view in self {
container.addSubview(view)
}

view.addSubview(container)

installerBlock()
container.configureFrame { maker in
maker.container()
}
installerBlock()
configure(container: container, relation: relation, installerBlock: installerBlock)
return container
}
}
Loading

0 comments on commit 52c9f5a

Please sign in to comment.