簡體   English   中英

以 SwiftUI 模態呈現表

[英]Presenting Sheet modally in SwiftUI

我試圖在導航欄中選擇菜單項時顯示模式表。 但是,工作表不顯示。 調試后,我注意到 state 變量showSheet沒有得到更新,我有點不知道為什么它沒有更新。

很感謝任何形式的幫助。 謝謝!

還有另一個帖子( @State not updates in SwiftUI 2 )也有類似的問題。 這是 SwiftUI 中的錯誤嗎?

下面是一個完整的樣本

我有一個fileprivate enum ,它為視圖定義了兩種情況 - addedit

fileprivate enum SheetView {
    case add, edit
}

下面是內容視圖。 ContentView 聲明了兩個基於所選菜單項設置的@State變量。菜單項 ( var actionItems ) 位於NavigationView上,並具有帶有 2 個按鈕的菜單 - 添加和編輯。 每個按鈕都有一個動作集來切換showSheetViewshowSheet變量。 根據選擇的項目來呈現內容。 內容是使用@ViewBuilder

struct ContentView: View {
    @State private var showSheetView = false
    @State private var showSheet: SheetView? = nil
    
    var body: some View {
        GeometryReader { g in
            NavigationView {
                Text("Main Page")
                    .padding()
                    .navigationBarTitle("Main Page")
                    .navigationBarItems(trailing: actionItems)
            }
        }.sheet(isPresented: $showSheetView) {
            content
        }
    }
    
    var actionItems: some View {
        Menu {
            Button(action: {
                showSheet = .add
                showSheetView.toggle()
            }) {
                Label("Add Asset", systemImage: "plus")
            }
            Button(action: {
                showSheet = .edit
                showSheetView.toggle()
            }) {
                Label("Edit Asset", systemImage: "minus")
            }
        } label: {
            Image(systemName: "dot.circle.and.cursorarrow").resizable()
        }
    }
    
    @ViewBuilder
    var content: some View {
        if let currentView = showSheet {
            switch currentView {
            case .add:
                AddAsset(showSheetView: $showSheetView)
            case .edit:
                EditAsset(showSheetView: $showSheetView)
            }
        }
    }
    
}

下面是兩個視圖 - AddAssetEditAsset

struct AddAsset: View {
    @Binding var showSheetView: Bool

    var body: some View {
        NavigationView {
            Text("Add Asset")
                .navigationBarTitle(Text("Add"), displayMode: .inline)
                .navigationBarItems(trailing: Button(action: {
                    print("Dismissing sheet view...")
                    self.showSheetView = false
                }) {
                    Text("Done").bold()
                })
        }
    }
}

struct EditAsset: View {
    @Binding var showSheetView: Bool
    var body: some View {
        NavigationView {
            Text("Edit Asset")
                .navigationBarTitle(Text("Edit"), displayMode: .inline)
                .navigationBarItems(trailing: Button(action: {
                    print("Dismissing sheet view...")
                    self.showSheetView = false
                }) {
                    Text("Done").bold()
                })
        }
    }
}

解決方案是使用sheet(item: variant.

這是固定代碼(有很多更改,因此包括所有組件)。 使用 Xcode 12.1 / iOS 14.1 測試

演示

enum SheetView: Identifiable {
    var id: Self { self }
    case add, edit
}

struct ContentView: View {
    @State private var showSheet: SheetView? = nil
    
    var body: some View {
        GeometryReader { g in
            NavigationView {
                Text("Main Page")
                    .padding()
                    .navigationBarTitle("Main Page")
                    .navigationBarItems(trailing: actionItems)
            }
        }.sheet(item: $showSheet) { mode in
            content(for: mode)
        }
    }
    
    var actionItems: some View {
        Menu {
            Button(action: {
                showSheet = .add
            }) {
                Label("Add Asset", systemImage: "plus")
            }
            Button(action: {
                showSheet = .edit
            }) {
                Label("Edit Asset", systemImage: "minus")
            }
        } label: {
            Image(systemName: "dot.circle.and.cursorarrow").resizable()
        }
    }
    
    @ViewBuilder
    func content(for mode: SheetView) -> some View {
        switch mode {
        case .add:
            AddAsset(showSheet: $showSheet)
        case .edit:
            EditAsset(showSheet: $showSheet)
        }
    }
    
}

struct AddAsset: View {
    @Binding var showSheet: SheetView?
    
    var body: some View {
        NavigationView {
            Text("Add Asset")
                .navigationBarTitle(Text("Add"), displayMode: .inline)
                .navigationBarItems(trailing: Button(action: {
                    print("Dismissing sheet view...")
                    self.showSheet = nil
                }) {
                    Text("Done").bold()
                })
        }
    }
}

struct EditAsset: View {
    @Binding var showSheet: SheetView?
    var body: some View {
        NavigationView {
            Text("Edit Asset")
                .navigationBarTitle(Text("Edit"), displayMode: .inline)
                .navigationBarItems(trailing: Button(action: {
                    print("Dismissing sheet view...")
                    self.showSheet = nil
                }) {
                    Text("Done").bold()
                })
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM