Skip to content

Commit 47e2f5d

Browse files
authored
Supports multiple describing layout blocks and layout containers in one place. #59
1 parent 166a633 commit 47e2f5d

File tree

2 files changed

+89
-23
lines changed

2 files changed

+89
-23
lines changed

Demo_MondrianLayout/Book.Overlay.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,30 @@ import UIKit
55
var _book_overlay: BookView {
66
BookNavigationLink(title: "Overlay") {
77

8+
BookPreview {
9+
ExampleView(width: nil, height: nil) { (view: UIView) in
10+
11+
view.mondrian.buildSubviews {
12+
UIView.mock(
13+
backgroundColor: .mondrianYellow,
14+
preferredSize: .init(width: 100, height: 100)
15+
)
16+
.viewBlock
17+
.overlay(
18+
UIView.mock(backgroundColor: .layeringColor)
19+
.viewBlock
20+
.overlay(
21+
UIView.mock(backgroundColor: .layeringColor)
22+
.viewBlock
23+
.padding(10)
24+
)
25+
.padding(10)
26+
)
27+
}
28+
}
29+
}
30+
31+
832
BookPreview {
933
ExampleView(width: nil, height: nil) { (view: UIView) in
1034
view.mondrian.buildSubviews {

MondrianLayout/Extensions/UIView+Mondrian.swift

Lines changed: 65 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,81 @@
11
import UIKit
22

3-
extension MondrianNamespace where Base : UIView {
3+
@resultBuilder
4+
public enum EntrypointBuilder {
45

5-
/**
6-
Applies the layout constraints
7-
Adding subviews included in layout
6+
public enum Either {
7+
case block(_LayoutBlockType)
8+
case container(LayoutContainer)
9+
}
810

9-
You might use ``LayoutContainer`` from describe beginning in order to support safe-area.
10-
*/
11-
@discardableResult
12-
public func buildSubviews<Block: _LayoutBlockType>(
13-
build: () -> Block
14-
) -> LayoutBuilderContext {
11+
public static func buildBlock(_ components: [Either]...) -> [Either] {
12+
return components.flatMap { $0 }
13+
}
1514

16-
let context = LayoutBuilderContext(targetView: base)
17-
let container = build()
18-
container.setupConstraints(parent: .init(view: base), in: context)
19-
context.prepareViewHierarchy()
20-
context.activate()
15+
public static func buildExpression<Block: _LayoutBlockType>(_ components: Block...) -> [Either] {
16+
return components.map { .block($0) }
17+
}
2118

22-
return context
19+
public static func buildExpression(_ components: LayoutContainer...) -> [EntrypointBuilder.Either] {
20+
return components.map { .container($0) }
2321
}
2422

23+
}
24+
25+
extension MondrianNamespace where Base : UIView {
26+
2527
/**
26-
Applies the layout constraints
27-
Adding subviews included in layout
28+
Builds subviews of this view.
29+
- activating layout-constraints
30+
- adding layout-guides
31+
- applying content-hugging, content-compression-resistance
32+
33+
You can start to describe like followings:
34+
35+
```swift
36+
view.mondrian.buildSubviews {
37+
ZStackBlock {
38+
...
39+
}
40+
}
41+
```
42+
43+
```swift
44+
view.mondrian.buildSubviews {
45+
LayoutContainer(attachedSafeAreaEdges: .vertical) {
46+
...
47+
}
48+
}
49+
```
50+
51+
52+
```swift
53+
view.mondrian.buildSubviews {
54+
LayoutContainer(attachedSafeAreaEdges: .vertical) {
55+
...
56+
}
57+
ZStackBlock {
58+
...
59+
}
60+
}
61+
```
2862
*/
2963
@discardableResult
30-
public func buildSubviews(
31-
build: () -> LayoutContainer
32-
) -> LayoutBuilderContext {
64+
public func buildSubviews(@EntrypointBuilder _ build: () -> [EntrypointBuilder.Either]) -> LayoutBuilderContext {
65+
66+
let entrypoints = build()
3367

3468
let context = LayoutBuilderContext(targetView: base)
35-
let container = build()
36-
container.setupConstraints(parent: base, in: context)
69+
70+
for entrypoint in entrypoints {
71+
switch entrypoint {
72+
case .block(let block):
73+
block.setupConstraints(parent: .init(view: base), in: context)
74+
case .container(let container):
75+
container.setupConstraints(parent: base, in: context)
76+
}
77+
}
78+
3779
context.prepareViewHierarchy()
3880
context.activate()
3981

0 commit comments

Comments
 (0)