SwiftUI:在枚举上切换.sheet,不起作用
我有两个 Modal/Popover.sheet我想根据用户按下哪个按钮来显示。我已经设置enum了不同的选项并设置了默认选项。
预期行为:
当用户选择任何选项时,将显示正确的工作表。当用户 THEN 选择其他选项时,它还会显示正确的工作表。
观察到的行为:
在下面的例子中,当用户第一次选择第二个选项时,显示第一个工作表,并将继续显示直到用户选择第一个工作表,然后它会开始切换。
调试打印显示@State变量正在更改,但是,工作表演示不会观察到此更改并按上述方式显示工作表。有什么想法吗?
import SwiftUI
//MARK: main view:
struct ContentView: View {
//construct enum to decide which sheet to present:
enum ActiveSheet {
case sheetA, sheetB
}
//setup needed vars and set default sheet to show:
@State var activeSheet = ActiveSheet.sheetA //sets default sheet to Sheet A
@State var showSheet = false
var body: some View {
VStack{
Button(action: {
self.activeSheet = .sheetA //set choice to Sheet A on button press
print(self.activeSheet) //debug print current activeSheet value
self.showSheet.toggle() //trigger sheet
}) {
Text("Show Sheet A")
}
Button(action: {
self.activeSheet = .sheetB //set choice to Sheet B on button press
print(self.activeSheet) //debug print current activeSheet value
self.showSheet.toggle() //trigger sheet
}) {
Text("Show Sheet B")
}
}
//sheet choosing view to display based on selected enum value:
.sheet(isPresented: $showSheet) {
switch self.activeSheet {
case .sheetA:
SheetA() //present sheet A
case .sheetB:
SheetB() //present sheet B
}
}
}
}
//MARK: ancillary sheets:
struct SheetA: View {
var body: some View {
Text("I am sheet A")
.padding()
}
}
struct SheetB: View {
var body: some View {
Text("I am sheet B")
.padding()
}
}
回答
对您的代码进行一些非常小的改动,您可以使用sheet(item:)它来防止出现此问题:
//MARK: main view:
struct ContentView: View {
//construct enum to decide which sheet to present:
enum ActiveSheet : String, Identifiable { // <--- note that it's now Identifiable
case sheetA, sheetB
var id: String {
return self.rawValue
}
}
@State var activeSheet : ActiveSheet? = nil // <--- now an optional property
var body: some View {
VStack{
Button(action: {
self.activeSheet = .sheetA
}) {
Text("Show Sheet A")
}
Button(action: {
self.activeSheet = .sheetB
}) {
Text("Show Sheet B")
}
}
//sheet choosing view to display based on selected enum value:
.sheet(item: $activeSheet) { sheet in // <--- sheet is of type ActiveSheet and lets you present the appropriate sheet based on which is active
switch sheet {
case .sheetA:
SheetA()
case .sheetB:
SheetB()
}
}
}
}
问题是,如果不使用item:,当前版本的 SwiftUI 会使用第一个状态值(即本例中的工作表 A)呈现初始工作表,并且不会在第一次演示时正确更新。使用这种item:方法可以解决问题。