-
Notifications
You must be signed in to change notification settings - Fork 0
/
StackBuilder.swift
129 lines (106 loc) · 3.2 KB
/
StackBuilder.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
//
// StackBuilder.swift
// XBSwiftBox
//
// Created by mac mini on 2024/3/21.
//
import UIKit
class SpacerView: UIView {
var contentSize = CGSize.zero
override var intrinsicContentSize: CGSize {
return contentSize
}
}
public class StackBuilder {
public private(set) var stackView: UIStackView
init(stackView: UIStackView) {
self.stackView = stackView
}
// MARK: - Public
@discardableResult
public func add(with some: Any) -> Self {
var obj: Any?
if some is StackBuilder {
let builder = some as! StackBuilder
obj = builder.stackView
} else if some is UIView {
obj = some as? UIView
}
guard let view = obj as? UIView else { return self }
stackView.addArrangedSubview(view)
return self
}
@discardableResult
public func add(_ closure: () -> Any) -> Self {
var obj = closure()
while obj is () -> Any {
let tmp = obj as! () -> Any
obj = tmp()
}
if obj is StackBuilder {
let builder = obj as! StackBuilder
obj = builder.stackView
}
guard let view = obj as? UIView else { return self }
stackView.addArrangedSubview(view)
return self
}
@discardableResult
public func remove(_ obj: Any) -> Self {
var view: Any
if obj is StackBuilder {
let builder = obj as! StackBuilder
view = builder.stackView
} else {
view = obj
}
guard let subview = view as? UIView else { return self }
stackView.removeArrangedSubview(subview)
return self
}
@discardableResult
public func insert(_ obj: Any, _ index: Int) -> Self {
var view: Any
if obj is StackBuilder {
let builder = obj as! StackBuilder
view = builder.stackView
} else {
view = obj
}
guard let subview = view as? UIView else { return self }
stackView.insertArrangedSubview(subview, at: index)
return self
}
@discardableResult
public func spacer(_ spacing: CGFloat) -> Self {
let lastView = stackView.arrangedSubviews.last
if lastView == nil {
addSpacer(spacing)
return self
}
if #available(iOS 11.0, *) {
stackView.setCustomSpacing(spacing, after: lastView!)
} else {
addSpacer(spacing)
}
return self
}
// MARK: - Private
private func addSpacer(_ spacing: CGFloat) {
let view = SpacerView()
view.backgroundColor = .clear
var size = CGSize.zero
if stackView.axis == .horizontal {
size = CGSize(width: spacing, height: 1)
} else {
size = CGSize(width: 1, height: spacing)
}
view.contentSize = size
stackView.addArrangedSubview(view)
}
}
public func buildStack(_ config: (UIStackView) -> Void) -> StackBuilder {
let stackView = UIStackView()
config(stackView)
return StackBuilder(stackView: stackView)
}