自从更新到Xcode 12 / iOS 14以来,我遇到了一些奇怪的行为。为验证此行为,我在测试应用中将其隔离了。
在我的原始应用中,我需要控制多个Sheet
。这就是为什么我要enum
区分当前活动的工作表并将其存储在@State private var activeSheet
中的原因。在@ViewBuilder
函数sheetContent()
中,返回所选View
的{{1}}。
对于此测试应用程序,出于简单起见,我仅实现了一张表格。
这是Sheet
的代码:
ContentView
这是枚举的代码:
struct ContentView: View {
@State private var showingSheet = false
@State private var activeSheet = ContentViewSheets.State.none
var body: some View {
Button(action: {
activeSheet = .aSheet
showingSheet = true // <-- ISSUE: activeSheet is still set to .none here!
}) {
Text("Open Sheet")
}
.sheet(isPresented: $showingSheet, content: sheetContent)
}
@ViewBuilder
private func sheetContent() -> some View {
switch activeSheet {
case .aSheet:
Text("I'm the right sheet!")
case .none:
Text("Oops! I'm not supposed to show up!")
}
}
}
如上面的ContentView代码中所述,class ContentViewSheets {
enum State {
case aSheet
case none
}
}
属性的值永远不会更改为activeSheet
,而是保持.aSheet
-这样就会显示错误的工作表。
这是bug还是我不正确理解Apple的.none
?他们只是在文档中写明,不得在初始化程序中使用它,而应在@State
中使用它,我肯定会这样做。
答案 0 :(得分:2)
在这种情况下,不要使用两种状态,而要使用一种明确设计的工作表修饰符。
通过Xcode 12 / iOS 14测试
class ContentViewSheets {
enum State: Identifiable {
case aSheet
case none
var id: State { self }
}
}
struct ContentView: View {
@State private var activeSheet: ContentViewSheets.State?
var body: some View {
Button(action: {
activeSheet = .aSheet
}) {
Text("Open Sheet")
}
.sheet(item: $activeSheet) {
sheetContent($0) // << activate state passed here !!!
}
}
@ViewBuilder
private func sheetContent(_ state: ContentViewSheets.State) -> some View {
switch state {
case .aSheet:
Text("I'm the right sheet!")
default:
Text("Oops! I'm not supposed to show up!")
}
}
}