#swift #button #boolean #swiftui-navigationlink
Вопрос:
У меня есть простое навигационное представление с 2 навигационными ссылками. Я пытаюсь создать функциональность, чтобы в одном из представлений назначения я мог вызвать логическое значение, чтобы ссылка на второе представление назначения больше не была доступна. Вот мой код:
import Foundation
class TestBool: ObservableObject {
@Published var testBool = false
}
extension Bool {
mutating func toggle() {
self = !self
}
}
Представление содержимого:
struct ContentView: View {
@EnvironmentObject var boolChange: TestBool
var body: some View {
NavigationView{
VStack{
NavigationLink("Screen One", destination: ScreenOneView())
NavigationLink("Screen Two", destination: ScreenTwoView(), isActive: .constant(boolChange.testBool == true))
Text("Hello, world!")
.padding()
}
.environmentObject(boolChange)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
.environmentObject(TestBool())
}
}
Просмотр экрана:
import SwiftUI
struct ScreenOneView: View {
@EnvironmentObject var boolItem: TestBool
var body: some View {
VStack {
Text("Hello, World!")
Button("This changes the Bool") {
self.boolItem.testBool.toggle()
}
}
}
}
struct ScreenOneView_Previews: PreviewProvider {
static var previews: some View {
ScreenOneView()
}
}
ScreenTwoView-это всего лишь пример экрана:
struct ScreenTwoView: Hashable, View {
var body: some View {
Text("Hello, World!")
}
}
I’ve added .environmentObject(boolChange)
in ScreenOneView
, that didn’t make a difference. Is there a way to make the NavigationLink to ScreenTwoView
appear/disappear based on the change in the Boolean in ScreenOneView
, and does the button in ScreenOneView
change the Boolean?
Update below
I managed to make the code work by providing using only @State
and @Binding
, and removing the reference to class
. I don’t like this solution as it isn’t flexible and I wouldn’t be able to scale this over multiple views. Refer to the updated code below:
extension Bool {
mutating func toggle() {
self = !self
}
}
Updated ContentView:
import SwiftUI
struct ContentView: View {
@State private var activeLink = true
var body: some View {
NavigationView{
VStack{
NavigationLink("Screen One", destination: ScreenOneView(activeLink: $activeLink))
NavigationLink(destination: ScreenTwoView()) { Text("Screen Two")}.disabled(activeLink)
NavigationLink(destination: ScreenThreeView()) { Text("Screen Three")}.disabled(!activeLink)
Text("Hello, world!")
.padding()
}
}
}
}
struct ContentView_Previews: PreviewProvider {
@State static var boolChange = false
static var previews: some View {
ContentView()
}
}
Updated ScreenOneView:
struct ScreenOneView: View {
@Binding var activeLink: Bool
var body: some View {
VStack {
Text("Hello, World!")
Button("This changes the Bool") {
activeLink.toggle()
}
}
}
}
struct ScreenOneView_Previews: PreviewProvider {
static var previews: some View {
ScreenOneView(activeLink: .constant(false))
}
}
Оба ScreenTwoView
и ScreenThreeView
являются стандартными представлениями SwiftUI, отображающими только Hello World!
button
Теперь активирует один и деактивирует другой NavigationLink
— точно так, как я пытался сделать.
Но я хочу масштабировать это и перейти к @ObservableObject
решению. Когда я пытаюсь это сделать, включая создание activeLink
@Published var
из Class TestBool
, я получаю много сообщений об ошибках и Previews
больше не работаю. Я новичок в Swift, может кто-нибудь, пожалуйста, дать некоторые рекомендации?