Представление оповещения в SwiftUI с использованием MVVM - PullRequest
2 голосов
/ 06 февраля 2020

Я пытаюсь создать приложение, используя SwiftUI и архитектуру MVVM. Я хотел бы, чтобы мой View представлял оповещение всякий раз, когда его ViewModel считает это необходимым, например, когда у него есть какой-либо новый результат, доступный из модели. Поэтому предположим, что всякий раз, когда виртуальная машина обнаруживает новый результат, она соответственно устанавливает status:

Модель представления:

enum Status {
    case idle
    case computing
    case newResultAvailable
}

class MyViewModel: ObservableObject {

    @Published var status = Status.idle

    ...
}

Представление:

struct ContentView: View {

    @ObservedObject var vm = MyViewModel()

    @State private var announcingResult = false {
        didSet {
            // reset VM status when alert is dismissed
            if announcingResult == false {
                vm.status = .idle
            }
        }
    }

    var body: some View {
        Text("Hello")
        .alert(isPresented: $announcingResult) {
            Alert(title: Text("There's a new result!"),
                message: nil,
                dismissButton: .default(Text("OK")))
        }
    }
}

Apple разработала модификатор .alert(), чтобы принимать привязку в качестве первого аргумента, чтобы предупреждение отображалось всякий раз, когда связанное свойство становится true. Затем, когда предупреждение отклоняется, свойство привязки автоматически устанавливается на false.

Мой вопрос: Как я могу отображать предупреждение, когда виртуальная машина status становится .newResultAvailable? Мне кажется, что именно так должен работать надлежащий MVVM, и он ощущается в духе всех демонстраций SwiftUI WWD C, но я не могу найти способ ...

1 Ответ

3 голосов
/ 06 февраля 2020

Здесь возможен подход (проверено и работает с Xcode 11.3 +)

struct ContentView: View {

    @ObservedObject var vm = MyViewModel()

    var body: some View {
        let announcingResult = Binding<Bool>(
            get: { self.vm.status == .newResultAvailable },
            set: { _ in self.vm.status = .idle }
        )
        return Text("Hello")
            .alert(isPresented: announcingResult) {
                Alert(title: Text("There's a new result!"),
                    message: nil,
                    dismissButton: .default(Text("OK")))
            }
    }
}

также иногда могут быть предпочтительны следующие обозначения

var body: some View {
    Text("Hello")
        .alert(isPresented: Binding<Bool>(
            get: { self.vm.status == .newResultAvailable },
            set: { _ in self.vm.status = .idle }
        )) {
            Alert(title: Text("There's a new result!"),
                message: nil,
                dismissButton: .default(Text("OK")))
        }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...