【问题标题】:Dismissing view using ObservableObject class provokes Publishing changes from within view updates is not allowed使用 ObservableObject 类关闭视图会引发在视图更新中发布更改是不允许的
【发布时间】:2023-02-04 03:18:56
【问题描述】:

当使用 ObservableObject 中的变量关闭 fullScreenCover 时(用 1.- 注释的行),它显示“不允许从视图更新中发布更改,这将导致未定义的行为。”消息,但使用 @State 变量(用 2.- 注释的行)不显示警告。我不懂为什么。

这是代码:

import SwiftUI

final class DismissWarningVM: ObservableObject {
    @Published var showAnotherView = false
}

struct DismissWarningView: View {
    @StateObject private var dismissWarningVM = DismissWarningVM()
    
    @State private var showAnotherView = false
    
    var body: some View {
        VStack {
            HStack {
                Spacer()
                Button {
                    // 1.- This line provokes the warning
                    dismissWarningVM.showAnotherView = true
                    // 2.- This line DO NOT provokes the warning
                    //showAnotherView = true
                } label: {
                    Text("Show")
                }
            }
            .padding(.trailing, 20)
            Spacer()
            Text("Main view")
            Spacer()
            
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .background(.white)
        // 1.- This line provokes the warning
        .fullScreenCover(isPresented: $dismissWarningVM.showAnotherView) {
        // 2.- This line DO NOT provokes the warning
        //.fullScreenCover(isPresented: $showAnotherView) {
            AnotherView()
        }
    }
}

struct AnotherView: View {
    @Environment(\.dismiss) var dismiss
    
    var body: some View {
        VStack(spacing: 30) {
            Text("Another view")
            Button {
                dismiss()
            } label: {
                Text("Dismiss")
                    .foregroundColor(.red)
            }
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .ignoresSafeArea()
    }
}

struct DismissWarningView_Previews: PreviewProvider {
    static var previews: some View {
        DismissWarningView()
    }
}

【问题讨论】:

标签: swiftui dismiss observableobject


【解决方案1】:

@StateObject 不是为视图模型对象设计的。在 SwiftUI 中,View 结构已经是视图模型了,你不需要另一个。请记住,SwiftUI 正在区分这些结构并自动为我们创建/更新/删除 UIView 对象。如果您使用视图模型对象,那么您将拥有 viewModel object -> View struct -> UIView object ,这是一团糟并且会导致错误。 @StateObject 专为需要 @State 中的引用类型而设计,鉴于我们有 .task.task(id:) 用于异步功能,现在这种情况并不常见。

您可以像这样实现您的需求:

struct WarningConfig {
    var isPresented = false

    // mutating func someLogic() {} 
}

struct SomeView: View {

    @State private var config = WarningConfig()

    ...

    .fullScreenCover(isPresented: $config.isPresented) {
        WarningView(config: $config)

【讨论】:

    猜你喜欢
    • 2022-10-04
    • 1970-01-01
    • 2022-10-02
    • 2020-07-31
    • 1970-01-01
    • 2023-02-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多