SwiftUI показать предупреждение на основе вычисляемого свойства - PullRequest
0 голосов
/ 27 октября 2019

Я пытаюсь показать предупреждение в Swift на основе вычисленного свойства. По сути, всякий раз, когда пользователь нажимает кнопку, значение «round» обновляется. Когда было выполнено более 10 раундов, появляется предупреждение.

Для этого я создал логическую переменную с именем «showAlert». Это должна быть переменная @State, чтобы снова установить значение false, когда пользователь закрывает предупреждение.

Однако компилятор сообщает мне, что оболочка свойства типа @State "не может быть применена к вычисляемому свойству":-(

Это код, который я пробовал:


@State var round = 0
@State var showingAlert:Bool {round > 10 ? true : false}

func result(player: Int, app: Int) {
if player > app {
 round += 1
 }
else {
 round += 1
}
}

var body: some View {
        Button(action: {self.result(player: 1, app: 1)}) {
        Text("Button")
        }
           .alert(isPresented: $showingAlert) {
                Alert(title: Text("title"), message: Text("message"), dismissButton: .default(Text("Continue"))
                )
} 

Есть ли способ обойти это? Я хотел бы создать предупреждение, которое отображается без сообщений об ошибках.

1 Ответ

1 голос
/ 27 октября 2019

Я предпочитаю помещать логику в модель - отделение логики от представления - но вот что работает:

@State var round = 0
@State var showingAlert:Bool = false

func result(player: Int, app: Int) {
    if player > app {
        round += 1
    } else {
        round += 1
    }
    if round > 10 {
        showingAlert.toggle()
    }
}

По сути, переместите свой чек в свою функцию. Примечания:

  • Я предполагаю, что это тестовая логика ... если нет, у вас есть опечатка в if/else, потому что они оба делают одно и то же.
  • Только установитьshowingAlert в true - пусть SwiftUI устанавливает его в значение false, когда предупреждение отклонено.
  • Реальная причина отделить эту логику от представления состоит в том, что вы можете упростить сброс * 1017. *. Вот код, который делает это:

import SwiftUI import Combine

class Model : ObservableObject {
    var objectWillChange = PassthroughSubject<Void, Never>()
    @Published var showingAlert = false {
        willSet {
            objectWillChange.send()
            if newValue == false {
                round = 0
            }
        }
    }
    var round = 0
    func result(player: Int, app: Int) {
        if player > app {
            round += 1
        } else {
            round += 1
        }
        if round > 10 {
            showingAlert.toggle()
        }
    }
}
struct ContentView: View {
    @EnvironmentObject var model: Model

    var body: some View {
        Button(action: {self.model.result(player: 1, app: 1)}) {
            Text("Button")
            }
        .alert(isPresented: self.$model.showingAlert) {
                Alert(title: Text("title"), message: Text("message"), dismissButton: .default(Text("Continue")))
            }
    }
}

Обратите внимание, что есть только одна переменная (showingAlert), помеченная как @Published, которую вы можетеправильно кодировать против willSet, и все, что вам нужно изменить в ContentView, это правильно добавить EnvironmentObject after your add it to your SceneDelegate`.

Первый набор кода будет отображать предупреждение после 11-го касания, а затемкаждый кран после этого. Второй набор кода будет показывать предупреждение после 11-го касания, а затем каждые 11 нажатий после этого.

...