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

时间:2019-11-13 03:11:01

标签: ios swiftui

我有以下(简化)的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:...)函数,则会设置错误消息,但是显示屏不会显示警报。

我猜想这与按钮位于视图内部而函数位于外部有关,但是我对如何修复它感到困惑。考虑到任何应用程序需要具有的功能来更新这样的显示,功能应该很容易。

1 个答案:

答案 0 :(得分:0)

好吧,更多的阅读和重构切换到使用像这样的可观察视图模型:

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 }
    }
}

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