SwiftUI - @State 属性未更新

Posted

技术标签:

【中文标题】SwiftUI - @State 属性未更新【英文标题】:SwiftUI - @State property is not updated 【发布时间】:2020-09-30 14:37:32 【问题描述】:

自从更新到 Xcode 12 / ios 14 后,我遇到了一些奇怪的行为。为了验证这种行为,我将它隔离在一个测试应用程序中。

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

对于这个测试应用,为了简单起见,我只实现了一张工作表。

这是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!")
        
    

这是枚举的代码:

class ContentViewSheets 
    enum State 
        case aSheet
        case none
    

正如上面 ContentView 代码中所注释的,activeSheet 属性的值永远不会更改为.aSheet,而是保持.none - 这样就会显示错误的工作表。

这是一个错误还是我没有正确理解 Apple 的 @State?他们只是在文档中写道,它不应在初始化程序中使用,而只能在 body 中使用,我肯定会这样做。

【问题讨论】:

确实有同样的问题! 【参考方案1】:

不要使用两种状态,而是使用一种明确设计的工作表修饰符来处理这种情况。

使用 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!")
            
    

【讨论】:

太好了,谢谢你,Asperi!非常优雅的解决方案!我仍然在努力理解为什么我的不起作用。似乎我不了解@State 属性的性质。 @Asperi 你是神。在过去的 4 个小时里,我一直在努力解决这个问题……至于 Ulrich,我不知道为什么它不起作用。我认为这绝对是一个错误。

以上是关于SwiftUI - @State 属性未更新的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI,为啥部分视图没有刷新? @State 变量未更新

SwiftUI @State 变量未更新

更新@State后未调用SwiftUI UIViewControllerRepresentable.updateUIViewController

SwiftUI @State 数组未更新在 init() 期间附加的值

SwiftUI:如何在函数计算 @State 值时同时更新视图?

SwiftUI 中子结构的计算属性未更新