@@ -270,7 +270,7 @@ public extension PillPickerView {
270270
271271}
272272
273- // MARK: - Child views
273+ // MARK: - Pill View
274274
275275/// View containing the selectable element
276276struct PillView < T: Pill > : View {
@@ -405,34 +405,63 @@ struct StaticStack<T, V>: View where T: Hashable, V: View {
405405 /// Chunk size which `items` is divided into
406406 @State private var chunkSize : Int = 1
407407
408+ /// Current total height calculated
409+ @State private var totalHeight = CGFloat . zero
410+
408411 private func calculateChunkSize( geometry: GeometryProxy ) {
409412 let availableWidth = geometry. size. width
410413 let itemWidth : CGFloat = 100
411414
412- chunkSize = max ( Int ( availableWidth / itemWidth) , 1 )
415+ chunkSize = max ( Int ( availableWidth / ( itemWidth + options. horizontalSpacing) ) , 1 )
416+ }
417+
418+ // MARK: - Height Calculation
419+
420+ /// Used to calculate the total height of the view. It wraps the ZStack
421+ /// in a GeometryReader to obtain the height of the content and updates
422+ /// the `totalHeight` state variable accordingly.
423+ private func viewHeightReader( _ binding: Binding < CGFloat > ) -> some View {
424+ return GeometryReader { geometry -> Color in
425+ let rect = geometry. frame ( in: . local)
426+ DispatchQueue . main. async {
427+ binding. wrappedValue = rect. size. height
428+ }
429+ return . clear
430+ }
413431 }
414432
415433 var body : some View {
416- GeometryReader { geometry in
417- VStack ( alignment: options. staticAlignment, spacing: options. verticalSpacing) {
418- ForEach ( items. chunked ( into: chunkSize) , id: \. self) { chunk in
419- HStack ( spacing: options. horizontalSpacing) {
420- ForEach ( chunk, id: \. self) { item in
421- viewGenerator ( item)
434+ VStack {
435+ GeometryReader { geometry in
436+ VStack ( spacing: options. verticalSpacing) {
437+ ForEach ( items. chunked ( into: chunkSize) , id: \. self) { chunk in
438+ HStack ( spacing: options. horizontalSpacing) {
439+ ForEach ( chunk, id: \. self) { item in
440+ viewGenerator ( item)
441+ }
422442 }
443+ . frame ( width: geometry. size. width, alignment: options. wrappingAlignment)
423444 }
424445 }
425- }
426- . onAppear {
427- calculateChunkSize ( geometry: geometry)
428- }
429-
430- /// Dynamically generate chunk size based on
431- /// screen direction and dimension
432- . onChange ( of: geometry. size. width) { _ in
433- calculateChunkSize ( geometry: geometry)
446+
447+ /// Necessary to get generated height
448+ /// of child elements combined, then
449+ /// set the parent `VStack` height accordingly
450+ . background ( viewHeightReader ( $totalHeight) )
451+
452+ . onAppear {
453+ calculateChunkSize ( geometry: geometry)
454+ }
455+
456+ /// Dynamically generate chunk size based on
457+ /// screen direction and dimension
458+ . onChange ( of: geometry. size. width) { _ in
459+ calculateChunkSize ( geometry: geometry)
460+ }
434461 }
435462 }
463+ . frame ( height: totalHeight)
464+ . frame ( maxWidth: . infinity)
436465 }
437466}
438467
@@ -481,7 +510,7 @@ public struct FlowStack<T, V>: View where T: Hashable, V: View {
481510 generateContent ( in: geometry)
482511 }
483512 }
484- . frame ( maxHeight : totalHeight)
513+ . frame ( height : totalHeight)
485514 }
486515
487516 // MARK: - Content Generation
@@ -512,7 +541,7 @@ public struct FlowStack<T, V>: View where T: Hashable, V: View {
512541 /// to 0 and subtracts the item's height from height to move to the next row.
513542 /// Otherwise, it returns the current `width` value and updates `width` by subtracting the item's width.
514543 func calculateLeadingAlignment( dimension: ViewDimensions , item: T ) -> CGFloat {
515- if abs ( width - ( dimension. width + dimension . width / 2 ) ) > geometry. size. width {
544+ if abs ( width - dimension. width) > geometry. size. width {
516545 width = 0
517546 height -= dimension. height
518547 }
@@ -537,19 +566,18 @@ public struct FlowStack<T, V>: View where T: Hashable, V: View {
537566 }
538567
539568 }
569+ }
540570
541- // MARK: - Height Calculation
542-
543- /// Used to calculate the total height of the view. It wraps the ZStack
544- /// in a GeometryReader to obtain the height of the content and updates
545- /// the `totalHeight` state variable accordingly.
546- private func viewHeightReader( _ binding: Binding < CGFloat > ) -> some View {
547- return GeometryReader { geometry -> Color in
548- let rect = geometry. frame ( in: . local)
549- DispatchQueue . main. async {
550- binding. wrappedValue = rect. size. height
551- }
552- return . clear
571+ /// MARK: - Utility functions
572+
573+ /// Get height of context and set passed binding
574+ /// parameter based on received value
575+ func viewHeightReader( _ binding: Binding < CGFloat > ) -> some View {
576+ return GeometryReader { geometry -> Color in
577+ let rect = geometry. frame ( in: . local)
578+ DispatchQueue . main. async {
579+ binding. wrappedValue = rect. size. height
553580 }
581+ return . clear
554582 }
555583}
0 commit comments