すべてのコンテンツ上でローディングダイアログを表示
以下の「モデルクラス」と「モディファイア」を導入することで、すべてのコンテンツ上でローディングダイアログを表示します。
- DialogModel.swift
- DialogModifier.swift
DialogModel
ObservableObjectプロトコルに準拠したクラスです。
これを使用して、ダイアログをアクティブ・非アクティブします。
import Foundation
public enum DialogType {
case none
case loading
}
class DialogModel: NSObject, ObservableObject {
@Published var dialogType: DialogType = .none
}
Dialog モディファイア
DialogModelのdialogTypeに基づいてローディングダイアログをアクティブにします
オーバーレイは、ビューをコンテンツの上に配置するために使用されます
import SwiftUI
struct DialogModifier: ViewModifier {
@ObservedObject var dialogModel: DialogModel
func body(content: Content) -> some View {
content
.overlay(
Group {
switch dialogModel.dialogType {
case .loading:
VStack {
Text("Loading...")
ActivityIndicator(isAnimating: .constant(true), style: .large)
}
default:
EmptyView()
}
}
)
}
}
extension View {
func dialog(_ model: DialogModel) -> some View {
self.modifier(DialogModifier(dialogModel: model))
}
}
struct ActivityIndicator: UIViewRepresentable {
@Binding var isAnimating: Bool
let style: UIActivityIndicatorView.Style
func makeUIView(context: UIViewRepresentableContext<ActivityIndicator>) -> UIActivityIndicatorView {
return UIActivityIndicatorView(style: style)
}
func updateUIView(_ uiView: UIActivityIndicatorView, context: UIViewRepresentableContext<ActivityIndicator>) {
isAnimating ? uiView.startAnimating() : uiView.stopAnimating()
}
}
Dialog モディファイアを適用する
一番上の親ビューにDialogModelを生成し、@StateObjectで保持する
そして、この親ビューに.environmentObjectでDialogModelをセットし、DialogModifierを適用する
これで、DialogModelのdialogTypeを指定することで、アプリのコンテンツビュー(一番トップの親ビュー)からダイアログが表示されるようになります。
オーバーレイは、アタッチされているビューにのみ適用されます。 そのため、「ダイアログ」を他のすべてのコンテンツ上に表示するには、一番上の親ビューにオーバーレイを配置する必要があります。
import SwiftUI
@main
struct TDDApp: App {
// アプリ起動時にDialogModelをインスタンス
@StateObject var dialogModel = DialogModel()
var body: some Scene {
WindowGroup {
ContentView()
// アプリのコンテンツビュー(一番トップの親ビュー)に共有オブジェクトとして登録し、ダイアログのモディファイアを適応
.environmentObject(dialogModel)
.dialog(dialogModel)
}
}
}
ローディングダイアログを表示する
ダイアログを表示したいビューにDialogModelを取り込みます
@EnvironmentObject var dialogModel: DialogModel
その後、ダイアログを表示したいビューでローディングダイアログを表示
self.dialogModel.dialogType = .loading
その後、ダイアログを消す
self.dialogModel.dialogType = .none
参考