SwiftUI-@状态属性未更新

SwiftUI-@状态属性未更新,swiftui,Swiftui,自从升级到Xcode 12/iOS 14后,我经历了一些奇怪的行为。为了验证这种行为,我在一个测试应用程序中隔离了它 在我原来的应用程序中,我有多个工作表要控制。这就是为什么我使用enenum来区分当前活动的工作表,并将其存储在@State private var activeSheet中。在@ViewBuilder函数sheetContent()中,我返回所选工作表的视图 对于这个测试应用程序,出于简单的原因,我只实现了一个表单 以下是ContentView的代码: struct Conten

自从升级到Xcode 12/iOS 14后,我经历了一些奇怪的行为。为了验证这种行为,我在一个测试应用程序中隔离了它

在我原来的应用程序中,我有多个
工作表要控制。这就是为什么我使用en
enum
来区分当前活动的工作表,并将其存储在
@State private var activeSheet
中。在
@ViewBuilder
函数
sheetContent()
中,我返回所选
工作表的
视图

对于这个测试应用程序,出于简单的原因,我只实现了一个表单

以下是
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代码中所述,
activeSheet
属性的值从未更改为
.aSheet
,而是保持为
.none
,因此将显示错误的工作表


这是一个bug还是我没有正确理解苹果的
@状态
?他们只是在文档中写道,它不应该用在初始值设定项中,而只能用在
主体中,我肯定会这样做。

在这种情况下,使用一个明确设计的表单修饰符,而不是使用两种状态

使用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!")
            }
    }
}
类内容视图页{
枚举状态:可识别{
case aSheet
无案例
变量id:状态{self}
}
}
结构ContentView:View{
@状态私有变量activeSheet:ContentViewSheets.State?
var body:一些观点{
按钮(操作:{
activeSheet=.aSheet
}) {
正文(“开页”)
}
.sheet(项目:$activeSheet){
sheetContent($0)//一些视图{
开关状态{
案例.aSheet:
文本(“我是正确的工作表!”)
违约:
文本(“哎呀!我不应该出现!”)
}
}
}

太好了,谢谢你,Asperi!非常优雅的解决方案!我仍在努力理解我的解决方案为什么不起作用。似乎我不理解@State properties的本质。@Asperi你是上帝。我在过去的4个小时里一直在为这个问题苦苦挣扎……至于Ulrich,我不知道它为什么不起作用。我认为这肯定是一个bug。有完全一样的问题!
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!")
            }
    }
}