我有两个模态/弹出框 .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()
}
}
答案 0 :(得分:5)
对您的代码进行一些非常小的改动,您可以使用 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:
方法可以解决问题。