繁体   English   中英

SwiftUI @State 在通过单独的方法更改值时不会触发更新

[英]SwiftUI @State not triggering update when value changed by separate method

我有一个 SwiftUI 显示器的这段(简化的)代码:

struct ContentView: View {

    private var errorMessage: String?
    @State private var showErrors: Bool = false

    var errorAlert: Alert {
        Alert(title: Text("Error!"), 
            message: Text(errorMessage ?? "oops!"), 
            dismissButton: .default(Text("Ok")))
    }

    init() {}

    var body: some View {
        VStack {
            Text("Hello, World!")
            Button(action: {
                self.showErrors.toggle()
            }) {
                Text("Do it!")
            }
        }
        .alert(isPresented: $showErrors) { errorAlert }
    }

    mutating func display(errors: [String]) {
        errorMessage = errors.joined(separator: "\n")
        showErrors.toggle()
    }
}

当视图显示时,我录制了“Do it”。 按钮,然后按预期显示警报。

但是,如果我调用display(errors:...) function 会设置错误消息,但显示屏不会发出警报。

我猜这与视图内部的按钮和外部的 function 有关,但我不知道如何修复它。 考虑到任何应用程序需要更新这样的显示的功能量应该很容易。

好的,更多阅读和重构切换到使用可观察视图 model ,如下所示:

class ContentViewModel: ObservableObject {

    var message: String? = nil {
        didSet {
            displayMessage = message != nil
        }
    }

    @Published var displayMessage: Bool = false
}

struct ContentView: View {

    @ObservedObject private var viewModel: ContentViewModel

    var errorAlert: Alert {
        Alert(title: Text("Error!"), message: Text(viewModel.message ?? "oops!"), dismissButton: .default(Text("Ok")))
    }

    init(viewModel: ContentViewModel) {
        self.viewModel = viewModel
    }

    var body: some View {
        VStack {
            Button(action: {
                self.viewModel.displayMessage.toggle()
            }) {
                Text("Do it!")
            }
        }
        .alert(isPresented: $viewModel.displayMessage) { errorAlert }
    }
}

现在按预期工作。 所以从中得出的结论是,即使在像这样更简单的代码中,使用可观察视图模型也更有用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM