Skip to content

Commit 160e34e

Browse files
authored
Merge pull request #22 from iWECon/enhance
Fix some bugs
2 parents 05cfb01 + 4c0b8bc commit 160e34e

11 files changed

+269
-51
lines changed

Demo/Demo/HVStackDemoViewController.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ class HVStackDemoViewController: UIViewController {
4242

4343
Spacer()
4444

45-
VStackView {
45+
VStackView(distribution: .fillWidth(spacing: 10)) {
4646

4747
// view.stack.then (Inspired by Then [ https://github.com/devxoul/Then ])
4848
UILabel().stack.then { label in
@@ -51,11 +51,11 @@ class HVStackDemoViewController: UIViewController {
5151
label.textColor = .red
5252
}
5353

54-
Spacer(length: 6)
54+
// Spacer(length: 6)
5555
// Support Divider (Inspired by SwiftUI)
5656
Divider(color: UIColor.orange)
5757

58-
Spacer(length: 6)
58+
// Spacer(length: 6)
5959

6060
UILabel().stack.then { label in
6161
label.text = "Version: 1"

Demo/Demo/HVStackWrapperViewDemoViewController.swift

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ let contentWidth: CGFloat = UIScreen.main.bounds.width - 32
1212

1313
class HVStackWrapperViewDemoViewController: UIViewController {
1414

15-
let content = VStackLayerWrapperView {
16-
HStackLayerWrapperView() {
17-
VStackLayerWrapperView(alignment: .left) {
15+
let content = VStackView {
16+
HStackView() {
17+
VStackView(alignment: .left) {
1818
UILabel().stack.then {
1919
$0.text = "Good Morning."
2020
$0.font = .systemFont(ofSize: 16, weight: .medium)
@@ -31,7 +31,7 @@ class HVStackWrapperViewDemoViewController: UIViewController {
3131
Spacer()
3232

3333
// ICON
34-
HStackLayerWrapperView(distribution: .spacing(10)) {
34+
HStackView(distribution: .spacing(10)) {
3535
UIView().stack.size(34).then {
3636
$0.backgroundColor = .systemPink
3737
$0.layer.cornerRadius = 8
@@ -48,13 +48,13 @@ class HVStackWrapperViewDemoViewController: UIViewController {
4848

4949
Spacer(length: 20)
5050

51-
HStackLayerWrapperView {
52-
HStackLayerWrapperView(distribution: .spacing(6)) {
51+
HStackView {
52+
HStackView(distribution: .spacing(6)) {
5353
UIView().stack.size(60).then {
5454
$0.backgroundColor = .systemPink
5555
$0.layer.cornerRadius = 8
5656
}
57-
VStackLayerWrapperView(alignment: .left) {
57+
VStackView(alignment: .left) {
5858
UILabel().stack.then {
5959
$0.text = "Spending"
6060
$0.font = .systemFont(ofSize: 18)
@@ -68,12 +68,12 @@ class HVStackWrapperViewDemoViewController: UIViewController {
6868
}
6969
}
7070
Spacer()
71-
HStackLayerWrapperView(distribution: .spacing(6)) {
71+
HStackView(distribution: .spacing(6)) {
7272
UIView().stack.size(60).then {
7373
$0.backgroundColor = .systemPink
7474
$0.layer.cornerRadius = 8
7575
}
76-
VStackLayerWrapperView(alignment: .left) {
76+
VStackView(alignment: .left) {
7777
UILabel().stack.then {
7878
$0.text = "Income"
7979
$0.font = .systemFont(ofSize: 18)
@@ -89,7 +89,7 @@ class HVStackWrapperViewDemoViewController: UIViewController {
8989
}.stack.width(contentWidth).sizeToFit(.width)
9090

9191
Spacer(length: 30)
92-
HStackLayerWrapperView(alignment: .bottom) {
92+
HStackView(alignment: .bottom) {
9393
UILabel().stack.then {
9494
$0.text = "Transactions"
9595
$0.font = .systemFont(ofSize: 24, weight: .bold)
@@ -104,15 +104,15 @@ class HVStackWrapperViewDemoViewController: UIViewController {
104104
}.stack.width(contentWidth).sizeToFit(.width)
105105

106106
Spacer(length: 20)
107-
VStackLayerWrapperView(alignment: .left) {
107+
VStackView(alignment: .left) {
108108

109-
HStackLayerWrapperView {
109+
HStackView {
110110
UIView().stack.size(40).then {
111111
$0.backgroundColor = .systemPink
112112
$0.layer.cornerRadius = 12
113113
}
114114
Spacer(length: 10)
115-
VStackLayerWrapperView(alignment: .left) {
115+
VStackView(alignment: .left) {
116116
UILabel().stack.then {
117117
$0.text = "Freelance Work"
118118
$0.textColor = .black
@@ -139,6 +139,20 @@ class HVStackWrapperViewDemoViewController: UIViewController {
139139

140140
// Do any additional setup after loading the view.
141141

142+
143+
let textLayer = CATextLayer()
144+
textLayer.string = "This is CATextLayer in VStackLayerWrapperView2"
145+
textLayer.fontSize = 12
146+
textLayer.foregroundColor = UIColor.black.cgColor
147+
textLayer.contentsScale = UIScreen.main.scale
148+
149+
content.addContent {
150+
VStackLayerContainerView {
151+
Spacer(length: 20)
152+
textLayer
153+
}
154+
}
155+
142156
self.view.addSubview(content)
143157
}
144158

Demo/Demo/WrapStackDemoViewController.swift

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,33 @@
66
//
77

88
import UIKit
9+
import StackKit
910

1011
class WrapStackDemoViewController: UIViewController {
1112

1213
override func viewDidLoad() {
1314
super.viewDidLoad()
1415

1516
// Do any additional setup after loading the view.
17+
18+
let vStack = VStackView(distribution: .fillWidth(spacing: 10)) {
19+
UILabel().stack.then {
20+
$0.text = "StackKit"
21+
$0.font = .systemFont(ofSize: 18, weight: .semibold)
22+
$0.textColor = .black
23+
}
24+
Divider()
25+
UILabel().stack.then {
26+
$0.text = "Version 1.0.0"
27+
$0.font = .systemFont(ofSize: 14, weight: .regular)
28+
$0.textColor = .gray
29+
}
30+
}
31+
vStack.sizeToFit()
32+
vStack.frame.origin = CGPoint(x: 20, y: 120)
33+
34+
view.addSubview(vStack)
1635
}
17-
1836

1937
/*
2038
// MARK: - Navigation

Sources/StackKit/Enums.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ public enum HStackDistribution {
1616
case autoSpacing
1717

1818
/// The height of subviews are equal. `The height of the VStack needs to be given.`
19-
case fillHeight
19+
/// set `nil` means autoSpacing
20+
case fillHeight(spacing: CGFloat? = nil)
2021

2122
/// The width and height of subviews are equal. `The size of the HStack needs to be given.`
2223
case fill
@@ -39,7 +40,8 @@ public enum VStackDistribution {
3940
case autoSpacing
4041

4142
/// The widths are all equal. `The width of the VStack needs to be given.`
42-
case fillWidth
43+
/// set `nil` means autoSpacing
44+
case fillWidth(spacing: CGFloat? = nil)
4345

4446
/// The widths and heights are all equal. `The size of the V Stack needs to be given.`
4547
case fill

Sources/StackKit/HStackView.swift

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ open class HStackView: UIView {
77

88
public required init(
99
alignment: HStackAlignment = .center,
10-
distribution: HStackDistribution = .autoSpacing,
10+
distribution: HStackDistribution = .spacing(2),
1111
@_StackKitHStackContentResultBuilder content: () -> [UIView] = { [] }
1212
) {
1313
super.init(frame: .zero)
@@ -69,9 +69,13 @@ open class HStackView: UIView {
6969
}
7070

7171
public var contentSize: CGSize {
72-
effectiveSubviews.map({ $0.frame }).reduce(CGRect.zero) { result, rect in
72+
let h = effectiveSubviews.map({ $0.frame }).reduce(CGRect.zero) { result, rect in
7373
result.union(rect)
74-
}.size
74+
}.width
75+
let w = effectiveSubviews.map({ $0.bounds }).reduce(CGRect.zero) { result, rect in
76+
result.union(rect)
77+
}.height
78+
return CGSize(width: h, height: w)
7579
}
7680

7781
open func hideIfNoEffectiveViews() {
@@ -114,12 +118,12 @@ open class HStackView: UIView {
114118
let spacing = autoSpacing()
115119
makeSpacing(spacing)
116120

117-
case .fillHeight:
121+
case .fillHeight(let spacing):
118122
fillDivider()
119123
fillSpecifySpacer()
120124
fillSpacer()
121125

122-
let spacing = autoSpacing()
126+
let spacing = spacing ?? autoSpacing()
123127
makeSpacing(spacing)
124128
fillHeight()
125129

@@ -206,8 +210,18 @@ extension HStackView {
206210
}
207211

208212
private func fillHeight() {
209-
effectiveSubviews.forEach {
210-
$0.frame.size.height = frame.height
213+
if frame.height == 0 {
214+
frame.size.height = contentSize.height
215+
}
216+
for subview in effectiveSubviews {
217+
let oldHeight = subview.frame.height
218+
subview.frame.size.height = frame.height
219+
220+
// fix #https://github.com/iWECon/StackKit/issues/21
221+
guard alignment == .center else {
222+
continue
223+
}
224+
subview.frame.origin.y -= (frame.height - oldHeight) / 2
211225
}
212226
}
213227

@@ -299,9 +313,13 @@ extension HStackView {
299313
} else {
300314
switch distribution {
301315
case .spacing(let spacing):
302-
unspacerViewsSpacing = spacing * CGFloat(unspacerViews.count - betweenInViewsCount - 1) // 正常 spacing 数量: (views.count - 1), spacer 左右的视图没有间距,所以需要再排除在 view 之间的 spacer 数量
316+
// 正常 spacing 数量: (views.count - 1), spacer 左右的视图没有间距,所以需要再排除在 view 之间的 spacer 数量
317+
unspacerViewsSpacing = spacing * CGFloat(unspacerViews.count - betweenInViewsCount - 1)
318+
319+
case .fillHeight(let spacing):
320+
unspacerViewsSpacing = (spacing ?? autoSpacing()) * CGFloat(unspacerViews.count - betweenInViewsCount - 1)
303321

304-
case .autoSpacing, .fillHeight:
322+
case .autoSpacing:
305323
unspacerViewsSpacing = autoSpacing() * CGFloat(unspacerViews.count - betweenInViewsCount - 1)
306324

307325
case .fill:
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
//
2+
// HStackLayerContainerView.swift
3+
//
4+
//
5+
// Created by i on 2022/10/9.
6+
//
7+
8+
import UIKit
9+
10+
open class HStackLayerContainerView: UIView {
11+
12+
public var hStackLayer: HStackLayer {
13+
self.layer as! HStackLayer
14+
}
15+
16+
open var alignment: HStackAlignment {
17+
get {
18+
hStackLayer.alignment
19+
}
20+
set {
21+
hStackLayer.alignment = newValue
22+
}
23+
}
24+
25+
open var distribution: HStackDistribution {
26+
get {
27+
hStackLayer.distribution
28+
}
29+
set {
30+
hStackLayer.distribution = newValue
31+
}
32+
}
33+
34+
public required init(
35+
alignment: HStackAlignment = .center,
36+
distribution: HStackDistribution = .autoSpacing,
37+
@_StackKitHStackLayerContentResultBuilder content: () -> [CALayer] = { [] }
38+
) {
39+
super.init(frame: .zero)
40+
hStackLayer.alignment = alignment
41+
hStackLayer.distribution = distribution
42+
43+
for v in content() {
44+
hStackLayer.addSublayer(v)
45+
}
46+
}
47+
48+
public required init?(coder: NSCoder) {
49+
super.init(coder: coder)
50+
}
51+
52+
open override class var layerClass: AnyClass {
53+
HStackLayer.self
54+
}
55+
56+
open override func sizeThatFits(_ size: CGSize) -> CGSize {
57+
hStackLayer.sizeThatFits(size)
58+
}
59+
60+
open func addContent(@_StackKitHStackLayerContentResultBuilder _ content: () -> [CALayer]) {
61+
hStackLayer.addContent(content)
62+
}
63+
64+
open func resetContent(@_StackKitHStackLayerContentResultBuilder _ content: () -> [CALayer]) {
65+
hStackLayer.resetContent(content)
66+
}
67+
68+
@available(*, deprecated, message: "use `addContent(_:)` or `resetContent(_:)` instead")
69+
open override func addSubview(_ view: UIView) {
70+
// deprecated
71+
}
72+
73+
}
74+

Sources/StackKit/Layer+LayerWraperView/HStackLayerWrapperView.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ import UIKit
55
///
66
/// 该类仅作展示使用,所有的 UIView 均会被转换为 CALayer 作为显示
77
///
8+
/// There may be performance problems in heavy use. It is recommended to use `VStackView` / `HStackView` when there are many views.
9+
/// 大量使用可能会有性能问题, 视图较多时建议使用 `VStackView` / `HStackView`
10+
///
811
open class HStackLayerWrapperView: _StackLayerWrapperView {
912

1013
public var hStackLayer: HStackLayer {

0 commit comments

Comments
 (0)