I’m new to SwiftUI and working on an app that fetches data from Firestore and displays it in a list view. When a user taps on an item, they are navigated to a detail view where they can view more information about the selected item and mark it as good by adding a bool for “g”. I’m trying to implement functionality to allow the user to navigate to the previous or next item in the detail view using buttons.
The main issue I’m facing is that I cannot access the correct order of the items in the detail view. In the list view, the items are ordered correctly based on a timestamp field, but I’m unable to access this order in the detail view to properly navigate between items.
Here’s a simplified version of my FirestoreDataView struct:
struct FirestoreDataView: View {
@State private var items = [RSSItem]()
// ... other state variables and properties
var body: some View {
NavigationStack {
List {
ForEach(items, id: .id) { item in
NavigationLink(value: item) {
RSSItemRow(item: item)
// ... other modifiers
}
}
// ... other view modifiers
}
.navigationDestination(for: RSSItem.self) { item in
if let index = items.firstIndex(where: { $0.id == item.id }) {
DetailView(item: $items[index], items: items, updateGField: updateGField)
}
}
}
// ... other view modifiers
}
// ... other functions and view builders
}
In the navigationDestination modifier, I’m passing the selected item and the entire items array to the DetailView. However, when I try to navigate between items in the detail view using the navigateToItem function, I encounter issues.
Here’s the relevant part of my DetailView struct:
swift
struct DetailView: View {
@Binding var item: RSSItem
let items: [RSSItem]
let updateGField: (RSSItem, Bool) -> Void
var body: some View {
// ... detail view layout
VStack {
// ... other buttons
Button(action: { navigateToItem(direction: .previous) }) {
Image(systemName: "arrow.up.circle.fill")
.foregroundColor(.blue)
.buttonStyle(CircleButtonStyle())
}
Button(action: { navigateToItem(direction: .next) }) {
Image(systemName: "arrow.down.circle.fill")
.foregroundColor(.blue)
.buttonStyle(CircleButtonStyle())
}
}
}
func navigateToItem(direction: NavigationDirection) {
guard let currentIndex = items.firstIndex(where: { $0.id == item.id }) else { return }
let newIndex: Int
switch direction {
case .previous:
newIndex = (currentIndex - 1 + items.count) % items.count
case .next:
newIndex = (currentIndex + 1) % items.count
}
item = items[newIndex]
}
}
I’ve tried several approaches to solve this issue, including:
- Using @Binding to pass the selected item and updating it in the navigateToItem function. However, this leads to the error:
ForEach<Array<RSSItem>, String, NavigationLink<ModifiedContent<ModifiedContent<ModifiedContent<ModifiedContent<ModifiedContent<ModifiedContent<ModifiedContent<RSSItemRow, _TraitWritingModifier<ListRowBackgroundTraitKey>>, SwipeActionsModifier<ModifiedContent<ModifiedContent<Button<ModifiedContent<Label<Text, Image>, _EnvironmentKeyWritingModifier<Optional<Color>>>>, _EnvironmentKeyTransformModifier<SymbolVariants>>, StyleContextWriter<SwipeActionsStyleContext>>>>, _TraitWritingModifier<SwipeActionsArePresent>>, StaticIf<InvertedViewInputPredicate<IsSharingPickerHost>, SharingPickerHostModifier, EmptyModifier>>, SwipeActionsModifier<ModifiedContent<ModifiedContent<Button<ModifiedContent<Label<Text, Image>, _EnvironmentKeyWritingModifier<Optional<Color>>>>, _EnvironmentKeyTransformModifier<SymbolVariants>>, StyleContextWriter<SwipeActionsStyleContext>>>>, _TraitWritingModifier<SwipeActionsArePresent>>, StaticIf<InvertedViewInputPredicate<IsSharingPickerHost>, SharingPickerHostModifier, EmptyModifier>>, Never>>: the ID ptT73BCKD2CRgstFqB7M occurs multiple times within the collection, this will give undefined results!
- Using @EnvironmentObject to share the items array across views. I created a DataModel class to hold the items array and injected it into the environment:
class DataModel: ObservableObject {
@Published var items = [RSSItem]()
}
struct FirestoreDataView: View {
@EnvironmentObject var dataModel: DataModel
// ...
}
struct DetailView: View {
@EnvironmentObject var dataModel: DataModel
// ...
}
However, this approach didn’t solve the issue, and I still couldn’t access the correct order of items in the detail view.
I’ve been struggling with this issue for a while now and would greatly appreciate any guidance or suggestions on how to properly navigate between items in the detail view while maintaining the correct order from the list view.
Thank you in advance for your help!