Another Question about Navigation/Routing
Patrick3131 opened this issue · comments
Hey Alex, thanks a lot for your example application.
I am creating another sample app based on the provided architecture of your example to get a better understanding of SwiftUI and Combine.
I have another problem with the navigation/routing. I basically copied your approach but I have these weird back and forth navigation behaviour, maybe you could take a look at my code. I have been going through the Stackoverflow topics, but I wasn't able to fix it and at the same time keep your routing example.
struct CategoriesList: View {
@Environment(\.locale) private var locale: Locale
@Environment(\.injected) private var injected: DIContainer
@State private var routingState: Routing = .init()
private var routingBinding: Binding<Routing> {
print(routingState)
return $routingState.dispatched(to: injected.appState, \.routing.categories)
}
private var categories = Category.allCases
var body: some View {
content
.onReceive(routingUpdate) { value in
print(value)
self.routingState = value
}
}
private var content: some View {
NavigationView {
List(self.categories) { category in
NavigationLink(
destination: Exercises(),
tag: category.rawValue,
selection: self.routingBinding.categories) {
CategorieCell(name: category.rawValue)
}
}.navigationBarTitle("Categories")
}
}
}
// MARK: - State Updates
private extension CategoriesList {
var routingUpdate: AnyPublisher<Routing, Never> {
injected.appState.updates(for: \.routing.categories)
}
}
extension CategoriesList {
struct Routing: Equatable {
var categories: String?
}
}
struct ExerciseDetail: View {
var body: some View {
Text("Hello DetailsView")
}
}
Link to the file:
https://github.com/Patrick3131/LearnHockey/blob/dev/LearnHockey/UI/Screens/CategoriesList.swift
Thanks!
Hi @Patrick3131
So I could find two issues in your code. The main one that was causing the weird back and forth navigation was this code:
extension Category: Identifiable {
var id: UUID { UUID()}
}
You are returning a random UUID each time this computed property is called, which totally confuses SwiftUI's list.
Here is a correct revision:
extension Category: Identifiable {
var id: String { self.rawValue }
}
Another issue is that you didn't inject the DIContainer
in the hierarchy, and the default value was used instead. You should do this:
var body: some View {
CategoriesList().inject(container)
}
Thanks a lot, it works!