【SwiftUI】LoadingView を実装してみる

API通信中などによくある、画面最前面に半透明で ProgressView を表示するサンプルを実装してみましたので紹介します。

【SwiftUI】LoadingView を実装してみる

LoadingView

ZStack を使って背景ホワイトで半透明の Rectangle の上に CircularProgressViewStyleProgressView(所謂クルクル)を乗せます(ProgressView についてこちらの記事をご参照ください)。

struct LoadingView: View {
    
    var body: some View {
        ZStack {
            Rectangle()
                .foregroundColor(.white)
                .opacity(0.6)
            ProgressView("")
        }
    }
}

AppControl(シングルトン)

LoadingViewいつでもどこでも呼び出せるようにしておきたいですよね。色々やり方はあるかと思いますが、ZStack で基底のView(以後 RootView) の背後に控えておき、zIndex を操作して出し入れする方法を取ってみました。

まず、zIndex を保持し、表示・非表示のメソッドを管理するクラスを作成します。

class AppControl: ObservableObject {
    
    static let shared = AppControl()
    
    @Published var zIndex: Double = 0.0
    
    func showLoading() {
        zIndex = 1.0
    }
    
    func hideLoading() {
        zIndex = 0.0
    }
}

AppControl のインスタンスを @main struct@StateObject 変数に保持させます。

次に、WindowGroupLoadingViewRootView(以下の例では ContentViewZStack で並べ、LoadingViewzIndexAppControlzIndex を紐付けます

@main
struct LoadingViewSampleApp: App {
    
    @StateObject private var appControl = AppControl.shared
    
    var body: some Scene {
        WindowGroup {
            ZStack {
                LoadingView().zIndex(appControl.zIndex)
                ContentView()
            }
        }
    }
}

zIndex のデフォルト値は 0.0 なので 初期状態では どちらも 0.0 となっていて、後に並んでいる ContentView が前に表示されます。

showLoading() を呼び出すことで zIndex が 1.0 になり、数値が大きい方が最前面に表示されるので LoadingView を登場させることができます。

hideLoading() で再び zIndex を 0.0 にして最背面に隠れることになります。

使用例

struct ContentView: View {
        
    var body: some View {
        ZStack {
            Rectangle()
                .foregroundColor(.yellow)
            Button("Start Loading") {
                AppControl.shared.showLoading()
                DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) {
                    AppControl.shared.hideLoading()
                }
            }
        }
    }
}

この例では、ボタン押下で表示し、3秒後に非表示になりますが、もちろん任意のタイミングで表示・非表示を制御できます。

以上、SwiftUI でのローティング画面の表示方法について紹介しました。

以下の関連記事も是非ご覧ください

【おすすめの関連記事】