我正在使用 swiftui 并且正在開發大型應用程式。我有太多的視圖,但我想顯示一個可以從應用程式內的任何視圖彈出的視圖。我幾乎不可能在每個 view.swift 上放置“.sheet”或“@State isPopUpShowing”。
有沒有辦法在不弄亂每個視圖檔案的情況下對我的彈出視窗進行一次/在一個檔案中編碼?
uj5u.com熱心網友回復:
您可以注入一個ObservableObject管理視圖層次結構根中的作業表(ContentView在我的示例中)并通過 using 傳播它.environmentObject。然后,子視圖將能夠訪問作業表管理器并從任何地方放置作業表。
class SheetManager : ObservableObject {
struct SheetItem : Identifiable {
var id = UUID()
var message : String
}
@Published var sheetItem : SheetItem?
@ViewBuilder func sheetForItem(item: SheetItem) -> some View {
Text(item.message)
}
func buildAndShowSheet(message : String) {
sheetItem = SheetItem(message: message)
}
}
struct ContentView: View {
@StateObject private var sheetManager = SheetManager()
var body: some View {
VStack {
Text("Hello, world!")
ChildView()
}
.sheet(item: $sheetManager.sheetItem) { item in
sheetManager.sheetForItem(item: item)
}
.environmentObject(sheetManager)
}
}
struct ChildView: View {
@EnvironmentObject private var sheetManager : SheetManager
var body: some View {
VStack {
Text("Child view that triggers sheet")
Button("Open sheet") {
sheetManager.buildAndShowSheet(message: "Sheet is open")
}
}
}
}
為了稍微高級一點,因為子視圖不需要回應來自作業表管理器的更新,您實際上可以將其設定為自定義環境鍵:
private struct SheetManagerKey: EnvironmentKey {
static let defaultValue = SheetManager()
}
extension EnvironmentValues {
var sheetManager: SheetManager {
get { self[SheetManagerKey.self] }
set { self[SheetManagerKey.self] = newValue }
}
}
class SheetManager : ObservableObject {
struct SheetItem : Identifiable {
var id = UUID()
var message : String
}
@Published var sheetItem : SheetItem?
@ViewBuilder func sheetForItem(item: SheetItem) -> some View {
Text(item.message)
}
func buildAndShowSheet(message : String) {
sheetItem = SheetItem(message: message)
}
}
struct ContentView: View {
@StateObject private var sheetManager = SheetManager()
var body: some View {
VStack {
Text("Hello, world!")
ChildView()
}
.sheet(item: $sheetManager.sheetItem) { item in
sheetManager.sheetForItem(item: item)
}
.environment(\.sheetManager, sheetManager)
}
}
struct ChildView: View {
@Environment(\.sheetManager) private var sheetManager
var body: some View {
VStack {
Text("Child view that triggers sheet")
Button("Open sheet") {
sheetManager.buildAndShowSheet(message: "Sheet is open")
}
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/337254.html
