Как я могу сделать навигационную ссылку обусловленной логическим набором в другом представлении?

#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, может кто-нибудь, пожалуйста, дать некоторые рекомендации?