11import UIKit
22
3- open class HStackLayer : CALayer , _StackLayerProvider {
3+ open class HStackLayer : CALayer , StackLayer {
44
55 public var alignment : HStackAlignment = . center
66 public var distribution : HStackDistribution = . autoSpacing
7+ public var padding : UIEdgeInsets = . zero
78
89 public required override init ( ) {
910 super. init ( )
@@ -19,13 +20,15 @@ open class HStackLayer: CALayer, _StackLayerProvider {
1920
2021 public required init (
2122 alignment: HStackAlignment = . center,
22- distribution: HStackDistribution = . autoSpacing,
23+ distribution: HStackDistribution = . spacing( 2 ) ,
24+ padding: UIEdgeInsets = . zero,
2325 @_StackKitHStackLayerContentResultBuilder content: ( ) -> [ CALayer ] = { [ ] }
2426 ) {
2527 super. init ( )
2628
2729 self . alignment = alignment
2830 self . distribution = distribution
31+ self . padding = padding
2932
3033 for l in content ( ) {
3134 addSublayer ( l)
@@ -46,9 +49,13 @@ open class HStackLayer: CALayer, _StackLayerProvider {
4649 }
4750
4851 public var contentSize : CGSize {
49- effectiveSublayers. map ( { $0. frame } ) . reduce ( CGRect . zero) { result, rect in
52+ let h = effectiveSublayers. map ( { $0. frame } ) . reduce ( CGRect . zero) { result, rect in
5053 result. union ( rect)
51- } . size
54+ } . width
55+ let w = effectiveSublayers. map ( { $0. bounds } ) . reduce ( CGRect . zero) { result, rect in
56+ result. union ( rect)
57+ } . height
58+ return CGSize ( width: h + paddingRight, height: w + paddingVertically)
5259 }
5360
5461 open override func preferredFrameSize( ) -> CGSize {
@@ -63,19 +70,23 @@ open class HStackLayer: CALayer, _StackLayerProvider {
6370 }
6471 }
6572
66- public override func layoutSublayers( ) {
67- super. layoutSublayers ( )
68-
69- refreshSublayers ( )
70-
73+ private func makeSublayersAlignment( ) {
7174 switch alignment {
7275 case . top:
73- effectiveSublayers. forEach { $0. frame. origin. y = 0 }
76+ effectiveSublayers. forEach { $0. frame. origin. y = _stackContentRect . minY }
7477 case . center:
75- effectiveSublayers. forEach { $0. position. y = frame . height / 2 }
78+ effectiveSublayers. forEach { $0. position. y = _stackContentRect . midY }
7679 case . bottom:
77- effectiveSublayers. forEach { $0. frame. origin. y = frame . height - $0. frame. height }
80+ effectiveSublayers. forEach { $0. frame. origin. y = _stackContentRect . maxY - $0. frame. height }
7881 }
82+ }
83+
84+ public override func layoutSublayers( ) {
85+ super. layoutSublayers ( )
86+
87+ refreshSublayers ( )
88+
89+ makeSublayersAlignment ( )
7990
8091 switch distribution {
8192 case . spacing( let spacing) :
@@ -93,12 +104,12 @@ open class HStackLayer: CALayer, _StackLayerProvider {
93104 let spacing = autoSpacing ( )
94105 makeSpacing ( spacing)
95106
96- case . fillHeight: // autoSpacing and fill height
107+ case . fillHeight( let spacing ) : // autoSpacing and fill height
97108 fillDivider ( )
98109 fillSpecifySpacer ( )
99110 fillSpacer ( )
100111
101- let spacing = autoSpacing ( )
112+ let spacing = spacing ?? autoSpacing ( )
102113 makeSpacing ( spacing)
103114 fillHeight ( )
104115
@@ -130,7 +141,7 @@ extension HStackLayer {
130141 let unspacerViews = viewsWithoutSpacer ( )
131142 let spacersCount = spacerLayers ( ) . map ( { isSpacerBetweenViews ( $0) } ) . filter ( { $0 } ) . count
132143 let number = unspacerViews. count - spacersCount - 1
133- return Swift . max ( 0 , ( frame. width - viewsWidth( ) - spacerSpecifyLength ( ) ) / CGFloat( max ( 1 , number) ) )
144+ return Swift . max ( 0 , ( frame. width - viewsWidth( ) - lengthOfAllFixedLengthSpacer ( ) ) / CGFloat( max ( 1 , number) ) )
134145 }
135146
136147 private func viewsWidth( ) -> CGFloat {
@@ -140,7 +151,7 @@ extension HStackLayer {
140151 private func makeSpacing( _ spacing: CGFloat ) {
141152 for (index, sublayer) in effectiveSublayers. enumerated ( ) {
142153 if index == 0 {
143- sublayer. frame. origin. x = 0
154+ sublayer. frame. origin. x = paddingLeft
144155 } else {
145156 let previousLayer = effectiveSublayers [ index - 1 ]
146157 if ( previousLayer as? SpacerLayer ) != nil || ( sublayer as? SpacerLayer ) != nil {
@@ -154,13 +165,21 @@ extension HStackLayer {
154165 }
155166
156167 private func fillHeight( ) {
157- effectiveSublayers. forEach {
158- $0. frame. size. height = frame. height
168+ if frame. height == 0 {
169+ frame. size. height = contentSize. height
170+ }
171+ for sublayer in effectiveSublayers {
172+ sublayer. frame. size. height = _stackContentWidth
173+
174+ guard alignment == . center else {
175+ continue
176+ }
177+ sublayer. position. y = _stackContentRect. midY
159178 }
160179 }
161180
162181 private func fillWidth( ) {
163- let maxW = frame. width - spacerSpecifyLength ( ) - dividerSpecifyLength ( )
182+ let maxW = frame. width - lengthOfAllFixedLengthSpacer ( ) - lengthOfAllFixedLengthDivier ( )
164183 var w = ( maxW) / CGFloat( viewsWithoutSpacerAndDivider ( ) . count)
165184
166185 let unspacersView = viewsWithoutSpacerAndDivider ( )
@@ -173,12 +192,6 @@ extension HStackLayer {
173192
174193extension HStackLayer {
175194
176- private func dividerSpecifyLength( ) -> CGFloat {
177- dividerLayers ( )
178- . map ( { $0. thickness } )
179- . reduce ( 0 , + )
180- }
181-
182195 private func fillDivider( ) {
183196 let maxWidth = effectiveSublayers. filter ( { ( $0 as? DividerLayer ) == nil } ) . map ( { $0. frame. size. height } ) . max ( ) ?? frame. height
184197 for divider in effectiveSublayers. compactMap ( { $0 as? DividerLayer } ) {
@@ -198,13 +211,6 @@ extension HStackLayer {
198211// MARK: Spacer
199212extension HStackLayer {
200213
201- // 取出固定 length 的 spacer
202- private func spacerSpecifyLength( ) -> CGFloat {
203- spacerLayers ( )
204- . map ( { $0. setLength } )
205- . reduce ( 0 , + )
206- }
207-
208214 private func isSpacerBetweenViews( _ spacer: SpacerLayer ) -> Bool {
209215 guard let index = effectiveSublayers. firstIndex ( of: spacer) else {
210216 return false
@@ -248,7 +254,10 @@ extension HStackLayer {
248254 case . spacing( let spacing) :
249255 unspacerViewsSpacing = spacing * CGFloat( unspacerViews. count - betweenInViewsCount - 1 ) // 正常 spacing 数量: (views.count - 1), spacer 左右的视图没有间距,所以需要再排除在 view 之间的 spacer 数量
250256
251- case . autoSpacing, . fillHeight:
257+ case . fillHeight( let spacing) :
258+ unspacerViewsSpacing = ( spacing ?? autoSpacing ( ) ) * CGFloat( unspacerViews. count - betweenInViewsCount - 1 )
259+
260+ case . autoSpacing:
252261 unspacerViewsSpacing = autoSpacing ( ) * CGFloat( unspacerViews. count - betweenInViewsCount - 1 )
253262
254263 case . fill:
@@ -258,7 +267,7 @@ extension HStackLayer {
258267
259268 // 非 spacerView 的所有宽度
260269 let unspacerViewsMaxWidth = unspacerViewsWidth + unspacerViewsSpacing
261- let spacersWidth = ( frame . width - unspacerViewsMaxWidth - self . spacerSpecifyLength ( ) )
270+ let spacersWidth = ( _stackContentWidth - unspacerViewsMaxWidth - self . lengthOfAllFixedLengthSpacer ( ) )
262271 let spacerWidth = spacersWidth / CGFloat( self . dynamicSpacerLayers ( ) . count)
263272
264273 let spacerViews = self . spacerLayers ( )
0 commit comments