@@ -4,6 +4,7 @@ public struct ProgressView<Label: View>: View {
44 private var label : Label
55 private var progress : Double ?
66 private var kind : Kind
7+ private var isSpinnerResizable : Bool = false
78
89 private enum Kind {
910 case spinner
@@ -23,7 +24,7 @@ public struct ProgressView<Label: View>: View {
2324 private var progressIndicator : some View {
2425 switch kind {
2526 case . spinner:
26- ProgressSpinnerView ( )
27+ ProgressSpinnerView ( isResizable : isSpinnerResizable )
2728 case . bar:
2829 ProgressBarView ( value: progress)
2930 }
@@ -50,6 +51,14 @@ public struct ProgressView<Label: View>: View {
5051 self . kind = . bar
5152 self . progress = value. map ( Double . init)
5253 }
54+
55+ /// Makes the ProgressView resize to fit the available space.
56+ /// Only affects `Kind.spinner`.
57+ public func resizable( _ isResizable: Bool = true ) -> Self {
58+ var progressView = self
59+ progressView. isSpinnerResizable = isResizable
60+ return progressView
61+ }
5362}
5463
5564extension ProgressView where Label == EmptyView {
@@ -101,7 +110,10 @@ extension ProgressView where Label == Text {
101110}
102111
103112struct ProgressSpinnerView : ElementaryView {
104- init ( ) { }
113+ let isResizable : Bool
114+ init ( isResizable: Bool = false ) {
115+ self . isResizable = isResizable
116+ }
105117
106118 func asWidget< Backend: AppBackend > ( backend: Backend ) -> Backend . Widget {
107119 backend. createProgressSpinner ( )
@@ -114,8 +126,33 @@ struct ProgressSpinnerView: ElementaryView {
114126 backend: Backend ,
115127 dryRun: Bool
116128 ) -> ViewUpdateResult {
117- ViewUpdateResult . leafView (
118- size: ViewSize ( fixedSize: backend. naturalSize ( of: widget) )
129+ let naturalSize = backend. naturalSize ( of: widget)
130+ guard isResizable else {
131+ // Required to reset its size when resizability
132+ // gets changed at runtime
133+ backend. setSize ( of: widget, to: naturalSize)
134+ return ViewUpdateResult . leafView ( size: ViewSize ( fixedSize: naturalSize) )
135+ }
136+ let min = max ( min ( proposedSize. x, proposedSize. y) , 10 )
137+ let size = SIMD2 (
138+ min,
139+ min
140+ )
141+ if !dryRun {
142+ // Doesn't change the rendered size of ProgressSpinner
143+ // on UIKitBackend, but still sets container size to
144+ // (width: n, height: n) n = min(proposedSize.x, proposedSize.y)
145+ backend. setSize ( of: widget, to: size)
146+ }
147+ return ViewUpdateResult . leafView (
148+ size: ViewSize (
149+ size: size,
150+ idealSize: naturalSize,
151+ minimumWidth: 10 ,
152+ minimumHeight: 10 ,
153+ maximumWidth: nil ,
154+ maximumHeight: nil
155+ )
119156 )
120157 }
121158}
0 commit comments