解放区在住氷翠 緑の閃光
【解放区在住氷翠】デスクトップアプリケーション

【SwiftUI】プログレスバーのこと

2023-02-16

こんばんは、氷翠です。

Mac M1
メモリ:16GB
MacOS:Ventura 13.1
Xcode:14.2

データをダウンロード、検索の進捗状況など、さまざまな場面で活用されるプログレスバーです。このSwiftuiでは「progressview」というらしい。しかし、どんなプログラム言語でもそうだったのだが、扱いが難しい。というか、よくわからんw

で、調べていって、勉強した結果、一つファイルで完結できるような感じ。

import SwiftUI

struct ContentView: View {
    
    @State private var text: String = ""
    @State private var val: Double = 0.00
    @State private var total: Double = 500
    
    var body: some View {
        VStack {
            Button("Start") {
                start()
            }
            ProgressView("\(text)", value: val, total: total)
        }
        .padding()
    }
    
    private func start() {
        text = "process:000/\(total)"
        DispatchQueue.global().asyncAfter(wallDeadline: .now()) {
            for _ in 0..<Int(total) {
                val += Double(1.0)
                text = "process:\(val)/\(total)"
                Thread.sleep(forTimeInterval: 0.05)
            }
            text = "complete!"
        }
    }
}

結局、「ContentView.swift」このメインになるファイル一つでOK。

今回も単純なレイアウトとして、ボタンとプログレスバーを用意しただけのものです。

で、プログレスバーで使用する変数として、文字が表示出来るので「text」という変数。現在の進捗状況を示している数値の変数「val」とプログレスの最大値「total」というのを宣言しておきます。

今回は長すぎても時間がかかるし、短すぎても変化がわかりずらいと思うので,500を最大値とした。

ボタンを押下したらその処理のメソッドが実行されるようになる。

さて、そのメソッドが問題。

この中でfor文で進捗状況を進めていく。

そして、問題なのは「DispatchQueue」これを使います。これは重い処理を実行させるものだそうで、その方法も「同期」「非同期」と二種類ある。さらにメインスレッドで実行していくか、バックグラウンドで実行させていくかというのもあり、今回は「非同期」をメインにした処理にするため、それを指定できる「global()」を利用。更に「非同期」を実現させる「asyncAfter」メソッドを利用する。

その中でfor文を展開して進捗状況を進めていく。

変数自体は同じstructの中なので、特に変数を参照とかするのではなく、そのまま使うことができるのでつかっていく。

で、実行するとなんとかうまく動作してくれました。

コメントを残す

メールアドレスが公開されることはありません。