Post

Replies

Boosts

Views

Activity

Reply to SwiftData Sectioning iOS 27
This error in TripListView indicates that the Query initializer you're calling expects a different type for the query result than the type being assigned to _trips. Your code: _trips = Query( filter: filter, sort: [sortDescriptor], sectionBy: sectionBy ) The key part of the error is: [Trip] and SectionedResults<Trip, String> must be equivalent. These are two different result types: [Trip] — a regular array of trips. SectionedResults<Trip, String> — sectioned query results grouped by a String key. Fix 1: If you want a regular list of trips If you don't need sections, remove sectionBy from the initializer: _trips = Query( filter: filter, sort: [sortDescriptor] ) Your property can remain: private var trips: [Trip] Fix 2: If you want trips grouped into sections If you're adapting Apple's sectioned TripListView, keep sectionBy, but declare the query result as sectioned results rather than [Trip]. For example, if the section key is a String: private var trips: SectionedResults<Trip, String> Then initialize the query: _trips = Query( filter: filter, sort: [sortDescriptor], sectionBy: sectionBy ) if you change declaration of trips like this: private var trips: SectionedResults<Trip, String> The issue is that @Query(sectionBy: \Trip.destination) always produces SectionedResults<Trip, String>. When sectionBy == nil, you want to show all trips in one ungrouped list, but your current code still groups them by destination. Because trips is declared as SectionedResults<Trip, String>, you cannot switch its underlying type to [Trip] conditionally in the initializer. The clean solution is to use two separate query properties: one sectioned and one unsectioned, and choose which one to display. Updated TripListView Keep both query types. When sectionBy is nil, render allTrips; otherwise, render the grouped sectionedTrips. import SwiftUI import SwiftData struct TripListView: View { @Environment(\.modelContext) private var modelContext // Unsectioned query: all trips @Query private var allTrips: [Trip] // Sectioned query: trips grouped by a String property @Query private var sectionedTrips: SectionedResults<Trip, String> @Binding var selection: Trip? @Binding var tripCount: Int @Binding var unreadTripIdentifiers: [PersistentIdentifier] private let sectionBy: KeyPath<Trip, String>? init( selection: Binding<Trip?>, segment: Binding<ContentView.Segment>, tripCount: Binding<Int>, unreadTripIdentifiers: Binding<[PersistentIdentifier]>, searchText: String, sectionBy: KeyPath<Trip, String>? = nil, sortDescriptor: SortDescriptor<Trip> = SortDescriptor(\Trip.startDate) ) { _selection = selection _tripCount = tripCount _unreadTripIdentifiers = unreadTripIdentifiers self.sectionBy = sectionBy let filter = Self.buildPredicate( segment: segment.wrappedValue, searchText: searchText ) // Always configure the unsectioned query. _allTrips = Query( filter: filter, sort: [sortDescriptor] ) // SectionedResults is required for this query. // Use destination as a fallback when sectionBy is nil. _sectionedTrips = Query( filter: filter, sort: [sortDescriptor], sectionBy: sectionBy ?? \Trip.destination ) } var body: some View { List(selection: $selection) { if sectionBy == nil { // Show all trips without section headers. ForEach(allTrips) { trip in TripListRow( trip: trip, isUnread: unreadTripIdentifiers.contains( trip.persistentModelID ) ) } } else { // Show trips grouped by the selected property. ForEach(sectionedTrips.sections) { section in Section(section.id) { ForEach(section) { trip in TripListRow( trip: trip, isUnread: unreadTripIdentifiers.contains( trip.persistentModelID ) ) } } } } } } } How to call it Show all trips, without grouping TripListView( selection: $selection, segment: $segment, tripCount: $tripCount, unreadTripIdentifiers: $unreadTripIdentifiers, searchText: searchText, sectionBy: nil ) Group trips by destination TripListView( selection: $selection, segment: $segment, tripCount: $tripCount, unreadTripIdentifiers: $unreadTripIdentifiers, searchText: searchText, sectionBy: \Trip.destination ) This works fine!!!
Topic: UI Frameworks SubTopic: SwiftUI
3w
Reply to SwiftData Sectioning iOS 27
This error in TripListView indicates that the Query initializer you're calling expects a different type for the query result than the type being assigned to _trips. Your code: _trips = Query( filter: filter, sort: [sortDescriptor], sectionBy: sectionBy ) The key part of the error is: [Trip] and SectionedResults<Trip, String> must be equivalent. These are two different result types: [Trip] — a regular array of trips. SectionedResults<Trip, String> — sectioned query results grouped by a String key. Fix 1: If you want a regular list of trips If you don't need sections, remove sectionBy from the initializer: _trips = Query( filter: filter, sort: [sortDescriptor] ) Your property can remain: private var trips: [Trip] Fix 2: If you want trips grouped into sections If you're adapting Apple's sectioned TripListView, keep sectionBy, but declare the query result as sectioned results rather than [Trip]. For example, if the section key is a String: private var trips: SectionedResults<Trip, String> Then initialize the query: _trips = Query( filter: filter, sort: [sortDescriptor], sectionBy: sectionBy ) if you change declaration of trips like this: private var trips: SectionedResults<Trip, String> The issue is that @Query(sectionBy: \Trip.destination) always produces SectionedResults<Trip, String>. When sectionBy == nil, you want to show all trips in one ungrouped list, but your current code still groups them by destination. Because trips is declared as SectionedResults<Trip, String>, you cannot switch its underlying type to [Trip] conditionally in the initializer. The clean solution is to use two separate query properties: one sectioned and one unsectioned, and choose which one to display. Updated TripListView Keep both query types. When sectionBy is nil, render allTrips; otherwise, render the grouped sectionedTrips. import SwiftUI import SwiftData struct TripListView: View { @Environment(\.modelContext) private var modelContext // Unsectioned query: all trips @Query private var allTrips: [Trip] // Sectioned query: trips grouped by a String property @Query private var sectionedTrips: SectionedResults<Trip, String> @Binding var selection: Trip? @Binding var tripCount: Int @Binding var unreadTripIdentifiers: [PersistentIdentifier] private let sectionBy: KeyPath<Trip, String>? init( selection: Binding<Trip?>, segment: Binding<ContentView.Segment>, tripCount: Binding<Int>, unreadTripIdentifiers: Binding<[PersistentIdentifier]>, searchText: String, sectionBy: KeyPath<Trip, String>? = nil, sortDescriptor: SortDescriptor<Trip> = SortDescriptor(\Trip.startDate) ) { _selection = selection _tripCount = tripCount _unreadTripIdentifiers = unreadTripIdentifiers self.sectionBy = sectionBy let filter = Self.buildPredicate( segment: segment.wrappedValue, searchText: searchText ) // Always configure the unsectioned query. _allTrips = Query( filter: filter, sort: [sortDescriptor] ) // SectionedResults is required for this query. // Use destination as a fallback when sectionBy is nil. _sectionedTrips = Query( filter: filter, sort: [sortDescriptor], sectionBy: sectionBy ?? \Trip.destination ) } var body: some View { List(selection: $selection) { if sectionBy == nil { // Show all trips without section headers. ForEach(allTrips) { trip in TripListRow( trip: trip, isUnread: unreadTripIdentifiers.contains( trip.persistentModelID ) ) } } else { // Show trips grouped by the selected property. ForEach(sectionedTrips.sections) { section in Section(section.id) { ForEach(section) { trip in TripListRow( trip: trip, isUnread: unreadTripIdentifiers.contains( trip.persistentModelID ) ) } } } } } } } How to call it Show all trips, without grouping TripListView( selection: $selection, segment: $segment, tripCount: $tripCount, unreadTripIdentifiers: $unreadTripIdentifiers, searchText: searchText, sectionBy: nil ) Group trips by destination TripListView( selection: $selection, segment: $segment, tripCount: $tripCount, unreadTripIdentifiers: $unreadTripIdentifiers, searchText: searchText, sectionBy: \Trip.destination ) This works fine!!!
Topic: UI Frameworks SubTopic: SwiftUI
Replies
Boosts
Views
Activity
3w