I can't for the life of me figure out how to only navigate if a property from my ObservedObject
changes to meet a condition. ie when my state changes to some condition, navigate to the next screen.
I've used the tag
and selection
initializer on the NavigationLink
but it selection
requires a Binding
, and I can't derive a Binding
from the properties on my ObservedObject
without using the .constant()
initializer on Binding
which is only an immutable value.
@ObservedObject var store: Store<AppState, AppValue>
NavigationLink(
destination: SecondView(),
tag: true,
selection: store.shouldNavigate // Can't do this because I need a binding
)
How else are people implementing buttons that only navigate if a condition in their state is met? I'm trying to avoid using the @State
because I want the navigation to depend on my app state not on a local state that I'm toggling based on some business logic
public final class Store<Value, Action>: ObservableObject {
@Published public private(set) var value: Value
}
UPDATE:
So it looks like I should be able to create a binding but since store.value
gives me Binding<Value>
I get an error: Generic parameter Subject cannot be inferred
.
just remove private(set)
in your model, NavigationLink
will set shouldNavigate
to false after navigation is completed, so it should not be private(set)
public final class Store<Value, Action>: ObservableObject {
@Published public var value: Value
}
I show you an important intermediate solution before generics. I think the key here is that selection binding
requires optional
binding. That's most hassles coming from.
enum AppState: String{
case none = "none"
case red = "red"
case blue = "blue"
case green = "green"
case purple = "purple"
}
enum AppValue: String{
case none
}
public final class Store<V, A>: ObservableObject {
@Published var value: AppState? = AppState.none
public var link :Color = Color.white
init(value: AppState = .none, link : Color = Color.white){
self.link = link
self.value = value
}
}
struct TestView: View {
@ObservedObject var store: Store<AppState?, AppValue>
var viewStates: [Store<AppState?,AppValue>] =
[Store(value: .red, link: Color.red),
Store(value: .blue, link: Color.blue) ,
Store(value: .green, link: Color.green),
Store(value: .purple, link: Color.purple) ]
var body: some View {
NavigationView{
VStack{
ForEach(viewStates, id: \.value){ s in
Group{
NavigationLink(destination: s.link, tag: s.value!, selection: self.$store.value ){EmptyView()}
Button( s.value!.rawValue, action: {
self.store.value = s.value!})
}}
}
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.