Инициализировать внешний вид оповещения - SwiftUI - PullRequest
0 голосов
/ 05 марта 2020

Уже несколько дней пытаюсь понять это, и пришло время обратиться за помощью. Я знаю, как это сделать с обычным Swift, но SwiftUI все еще немного отличается от меня на данный момент. У меня есть функция, которая проверяет, если что-то верно. Он проходит через 3 оператора if, если один равен true, тогда возвращает bool, который я создал как true. Как только одна из 3 верна, я хочу, чтобы всплыло определенное предупреждение. Я вставил все 3 Alert в тело: некоторые View с правильной переменной, но они не отображаются. Если я закомментирую 2 и оставлю 1 Alert без комментариев, это сработает. Так что я знаю, что мои заявления if верны Это просто то, как я представляю это телу, где я застрял. Смотрите ниже, и если у вас есть альтернатива.

    func showTip() {
            if (stepFive <= Float(18)) {
                under = true
            }

           else if (stepFive >= Float(18) && stepFive <= Float(18.5)) {
                thin = true
            }


           else if (stepFive >= 18.6) && (stepFive <= 24.9) {
                healthy = true
            }
    }

var body: some View {
        ZStack {
            Color.blue
            .edgesIgnoringSafeArea(.all)

            .alert(isPresented: $under) {
                Alert(title: Text("Results"), message: Text("A of less than 18 means you are under weight. "), dismissButton: .default(Text("OK")))
            }

            .alert(isPresented: $thin) {
                Alert(title: Text("Results"), message: Text("A of less than 18.5 indicates you are thin"), dismissButton: .default(Text("OK")))
            }

            .alert(isPresented: $healthy) {
                Alert(title: Text("Results"), message: Text("A between 18.6 and 24.9 indicates you are at a healthy"), dismissButton: .default(Text("OK")))
            }
}

1 Ответ

1 голос

ОБНОВЛЕНИЕ для отображения решения с функцией showTip:

struct ComplexAlertWith3Variables: View {

    @State var under = false
    @State var thin = false
    @State var healthy = false
    @State var stepFive: Float = 18.3 // I don't know how it changes. From somewhere. and it doesn't matter now

    private var messageText: String {
        return thin ? "A of less than 18.5 indicates you are thin" : "" // compute other variants
    }

    var body: some View {

        let needToShowAlert: Binding<Bool> = Binding<Bool>(
        get: { self.under || self.thin || self.healthy },
        set: { if $0 == false { self.under = $0; self.thin = $0; self.healthy = $0 } })

        return Text("Fire show tip function, because I don't know from where it fires in your code")
            .onTapGesture { self.showTip() } // fire your function. so you see, it doesn't matter from where you change variables
            .alert(isPresented: needToShowAlert) {
                Alert(title: Text("Results"), message: Text(self.messageText), dismissButton: .default(Text("OK")))
        }

    }

    // your function (makes it shorter to fit more lines of code)
    func showTip() {
        if (stepFive <= Float(18)) { under = true } 
        else if (stepFive >= Float(18) && stepFive <= Float(18.5)) { thin = true }
        else if (stepFive >= 18.6) && (stepFive <= 24.9) { healthy = true }
    }
}

результат при нажатии на текст ИЛИ запускает функцию из другого места:

enter image description here

Я немного поиграл с этим и думаю, что могу предложить вам одно решение. Речь идет о создании пользовательской Binding переменной и использовании ее в body. Кроме того, в первом варианте я написал решение с enum, но вы можете найти решение с 3 переменными и во фрагменте кода:

struct ComplexAlert: View {

    @State private var option: SomeOption = .unselected

    var body: some View {
        // DISCLAIMER: I wrote in a such a way to fit more lines of code on the page
        // the main here is an idea, not code style =)
        let needToShowAlert: Binding<Bool> = Binding<Bool>(
            get: { self.option != .unselected },
            set: { if $0 == false { self.option = .unselected } })

        return VStack {
            Button(action: { self.option = .under }) { Text("make under") }
            Button(action: { self.option = .thin }) { Text("make thin") }
            Button(action: { self.option = .healthy }) { Text("make healthy") }
        }
            .alert(isPresented: needToShowAlert) {
                Alert(title: Text("Results"), message: Text(self.option.getAlertMessage()), dismissButton: .default(Text("OK")))
        }
    }
}

// MARK: if you need to use 3 variables:
struct ComplexAlertWith3Variables: View {

    @State var under = false
    @State var thin = false
    @State var healthy = false

    private var messageText: String {
        return under ? "under" : "" // compute other varianst
    }

    var body: some View {

        let needToShowAlert: Binding<Bool> = Binding<Bool>(
        get: { self.under || self.thin || self.healthy },
        set: { if $0 == false { self.under = $0; self.thin = $0; self.healthy = $0 } })

        return Text("Hello")
            .onTapGesture { self.under = true }
            .alert(isPresented: needToShowAlert) {
                Alert(title: Text("Results"), message: Text(self.messageText), dismissButton: .default(Text("OK")))
        }

    }
}

// MARK: enum which was used in the first solution:
enum SomeOption {

    case unselected
    case under
    case thin
    case healthy

    func getAlertMessage() -> String {
        switch self {
        case .unselected:
            return ""
        case .under:
            return "A of less than 18 means you are under weight. "
        case .thin:
            return "A of less than 18.5 indicates you are thin"
        case .healthy:
            return "A between 18.6 and 24.9 indicates you are at a healthy"
        }
    }

}

результат для ComplexAlert будет:

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...