API通信中などによくある、画面最前面に半透明で ProgressView を表示するサンプルを実装してみましたので紹介します。
【SwiftUI】LoadingView を実装してみる
LoadingView
ZStack を使って背景ホワイトで半透明の Rectangle の上に CircularProgressViewStyle の ProgressView(所謂クルクル)を乗せます(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 変数に保持させます。
次に、WindowGroup に LoadingView と RootView(以下の例では ContentView)ZStack で並べ、LoadingView の zIndex に AppControl の zIndex を紐付けます。
@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 でのローティング画面の表示方法について紹介しました。
以下の関連記事も是非ご覧ください。
コメントを残す