【SwiftUI】View の 強制再描画

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 hatena-bookmark

しかし、これを、再スタートしようとすると、

できない。どうやるのこれ。


struct TestView: View {
  var body: some View {

    AutoProgressView()

    Button("restart") {
      // ?
    }

  }
}

たいそうにタイマーまで付けてやりたくない。

View をリフレッシュするだけでいい。

 

■ 強制再描画

「View に id を付けてそれを更新すればいい」らしい。

👉 id(_:) | Apple Developer Documentation hatena-bookmark


struct TestView: View {
  @State var id = false

  var body: some View {

    AutoProgressView()
      .id(id)

    Button("restart") {
      id.toggle()
    }

  }
}

 

■ まとめ

さすが、先人先生。

ありがとうございます。

👉 [SwiftUI] ViewのIdentityと再描画を意識しよう hatena-bookmark

ちなみに、task の中身のループは、スリープなしで破棄時に消化されているようです。