Как перемещаться с помощью кнопки с проверкой состояния в SwiftUI

Поскольку NavigationButton больше не доступен, как мне проверить условия в NavigationLink, чтобы перейти к другому представлению?


NavigationLink(destination: Dashboard(userName: self.userId, 
                                      password: self.password), isActive: $showDashboard) {

                    Button(action: {
                        if self.userId.isEmpty || self.password.isEmpty {
                            self.isAlert = true
                        } else {
                            self.showDashboard = true
                        }

                    }) {
                        Text("Submit")
                            .foregroundColor(.white)
                            .font(.system(size: 22))

                        Dashboard()
                    }
                    .frame(minWidth: 150, idealWidth: 300, maxWidth: 450, 
                     minHeight: 30, idealHeight: 40, maxHeight: 50, alignment: .center)
                    .background(Color(red: 81/255, green: 221/255, blue: 182/255))

                    .padding([.leading, .trailing], 20)
                } 

Редактировать:-

Кроме того, я хочу, чтобы показать предупреждение, если длина имени пользователя и пароля является более 16 и отличается оповещать, если длина больше, чем 10 и пустое сообщение предупреждения, если длина равна 0.

2 ответа

Решение

Вы можете сделать что-то вроде этого:

    NavigationView {
        VStack {
            NavigationLink(destination:  Dashboard(userName: self.userId, password: self.password), isActive: $showDashboard) {
                Text("")
            }
            Button(action: {
                 if self.userId.isEmpty || self.password.isEmpty {
                      self.isAlert = true
                  } else {
                      self.showDashboard = true
                  }
            }) {
                Text("Submit")
                    .foregroundColor(.green)
                    .font(.system(size: 22))

            }
        }
    }

Следует помнить, что NavigationLink - это сама кнопка, и при нажатии на нее осуществляется переход к destinationView, то isActiveПараметр - это способ заставить это произойти (без нажатия пользователем ссылки NavigationLink). На данный момент я не уверен, как встроить логику в NavigationLinks.

Надеюсь это поможет:)

РЕДАКТИРОВАТЬ:

Еще вы можете сделать следующее:

NavigationLink(destination:Dashboard(userName: self.userId, password: self.password)) {
                    Text("Submit")
                }.disabled(self.userId.isEmpty || self.password.isEmpty )

Это отключит NavigationLink, пока оба поля ввода не станут пустыми.

Я не уверен, хотите ли вы проверить условия, чтобы определить пункт назначения NavigationLink или отключен он или нет, но в этом примере кода показано, как это сделать:

struct ContentView: View {
    @State var userId = ""
    @State var password = ""

    var body: some View {
        NavigationView {
            NavigationLink(destination: (self.userId.isEmpty || self.password.isEmpty) ? AnyView(Dashboard(userName: self.userId, password: self.password)) : AnyView(Text("Different view")), isActive: Binding(get: {
                return self.userId.isEmpty || self.password.isEmpty
            }, set: { (_) in

            })) {
                Text("Navigate")
            }
        }
    }
}

Создайте настраиваемую привязку для isActive для оценки нескольких условий:

Binding(get: {
        return self.userId.isEmpty || self.password.isEmpty
}, set: { (_) in

})

И оцените условия в тернарном выражении, обязательно используяAnyViewдля Type Erasure, чтобы возвращать различные виды представлений, если вы хотите, чтобы условия определяли, какое представлениеNavigationLink переходит к:

(self.userId.isEmpty || self.password.isEmpty) ? AnyView(Dashboard(userName: self.userId, password: self.password) : AnyView(Text("Different view"))

Изменить: вы можете установить другой вид наnil если вы не хотите, чтобы представление переходило к чему-либо, если условное выражение оценивается как false:

(self.userId.isEmpty || self.password.isEmpty) ? AnyView(Dashboard(userName: self.userId, password: self.password) : nil

Изменить 2: если вы хотите, чтобы предупреждение отображалось при сбое условия, используйте указанную выше строку (сnil) для пункта назначения NavigationLink и добавьте предупреждение, у которого также есть настраиваемый Binding за isPresented:

.alert(isPresented: Binding(get: {
            return self.userId.isEmpty || self.password.isEmpty
    }, set: { (_) in

    })) {
        Text("Alert message")
    }

Вы можете добавить это предупреждение в любое подразделение в представлении с переменными, которые вы оцениваете (в этом случае ContentView).

Другие вопросы по тегам