ProgressView を使って簡単なインジケーターをつくる。
struct AutoProgressView: View {
@State private var value = 0.0
private let total = 10.0
private let duration = 1.0
var body: some View {
ProgressView(value: value, total: total)
.task {
while value < total {
try? await Task.sleep(for: .seconds(duration))
value += duration
}
}
}
}
便利ですねこれ。
ProgressView | Apple Developer Documentation
しかし、これを、再スタートしようとすると、
できない。どうやるのこれ。
struct TestView: View {
var body: some View {
AutoProgressView()
Button("restart") {
// ?
}
}
}
たいそうにタイマーまで付けてやりたくない。
View をリフレッシュするだけでいい。
■ 強制再描画
「View に id を付けてそれを更新すればいい」らしい。
id(_:) | Apple Developer Documentation
struct TestView: View {
@State var id = false
var body: some View {
AutoProgressView()
.id(id)
Button("restart") {
id.toggle()
}
}
}
■ まとめ
import SwiftUI | |
struct TestView: View { | |
@State var id = false | |
var body: some View { | |
AutoProgressView() | |
.padding() | |
.id(id) | |
Button("restart") { | |
id.toggle() | |
} | |
.buttonStyle(.borderedProminent) | |
} | |
} | |
struct AutoProgressView: View { | |
@State private var value = 0.0 | |
private let total = 10.0 | |
private let duration = 1.0 | |
var body: some View { | |
ProgressView(value: value, total: total) | |
.task { | |
while value < total { | |
try? await Task.sleep(for: .seconds(duration)) | |
value += duration | |
} | |
} | |
} | |
} | |
#Preview { | |
TestView() | |
} |
さすが、先人先生。
ありがとうございます。
[SwiftUI] ViewのIdentityと再描画を意識しよう
ちなみに、task の中身のループは、スリープなしで破棄時に消化されているようです。