Tuesday, April 9, 2024
HomeiOS Developmentios - Create sortable, ordered, and grouped knowledge from @Question in SwiftData

ios – Create sortable, ordered, and grouped knowledge from @Question in SwiftData


I have been attempting to wrap my head round a sorting and grouping course of for a SwiftUI app I have been attempting to construct.

All of the tutorials I’ve seen have been pretty “primary” in the case of the sorting and filtering facet – significantly when utilizing SwiftData.

What I wished to include was not solely sorting by one of many attributes and ahead/reverse, but additionally grouping the information too.

For instance, that is code from the Earthquake venture by Apple (some objects eliminated for brevity):

struct QuakeList: View {
    @Setting(ViewModel.self) personal var viewModel
    @Setting(.modelContext) personal var modelContext
    @Question personal var quakes: [Quake]

    init(
        sortParameter: SortParameter = .time,
        sortOrder: SortOrder = .reverse
    ) {
        swap sortParameter {
            case .time:
                _quakes = Question(type: .time, order: sortOrder)
            case .magnitude:
                _quakes = Question(type: .magnitude, order: sortOrder)
        }
    }

What they do in that is move within the sortParameter and the sortOrder to this view and it re-renders the view on change/replace.

How can I increase this so it can also deal with grouping so the quakes variable would actually be a multidimensional array or perhaps a dictionary.

For instance, I used to be attempting to do that to carry out the rendering:

enum GroupOption { // New grouping for Part
    case time
    case magnitude
    case none
}

struct ListScreen: View {
    @Setting(ViewModel.self) personal var viewModel
    @Setting(.modelContext) personal var modelContext
    @Question personal var quakes: [Quake]
    @State personal var groupedQuakes: [[Quake]] = [] // New multidimensional array

    init(
        sortParameter: SortParameter = .time,
        sortOrder: ComparisonResult = .orderedAscending, // utilizing ComparisonResult to retailer the enum worth in defaults
        sortGrouping: GroupOption = .none
    ) {
        swap (sortParameter, sortOrder) {
            case (.time, .orderedAscending):
                _quakes = Question(type: .time, order: .ahead)
            case (.time, .orderedDescending):
                _quakes = Question(type: .time, order: .reverse)

            case (.magnitude, .orderedAscending):
                _quakes = Question(type: .magnitude, order: .ahead)
            case (.magnitude, .orderedDescending):
                _quakes = Question(type: .magnitude, order: .reverse)

            default:
                _quakes = Question(type: .time, order: .ahead)
        }

        swap sortGrouping {
            case .time:
                groupedQuakes = Dictionary(grouping: _quakes.wrappedValue, by: { $0.time })
                    .sorted(by: { $0.key < $1.key })
                    .map({ $0.worth })
            case .magnitude:
                groupedQuakes = Dictionary(grouping: _quakes.wrappedValue, by: { $0.magnitude })
                    .sorted(by: { $0.key < $1.key })
                    .map({ $0.worth })
            case .none:
                groupedQuakes = [_quakes.wrappedValue]
        }
    }

Besides, after I use it within the view physique it’s empty. So switching from the // 1 to // 2 makes the array of information return empty.

// 1
Record(quakes, choice: $selectedId) { quake in
  QuakeRow(quake: quake)
}

// 2
Record {
  ForEach(groupedQuakes, id: .self) { group in
    Part {
      ForEach(group) { quake in
        QuakeRow(quake: quake)
      }
    } header: {
      groupHeader(for: group)
    }
  }
}
// ...
func groupHeader(for group: [Quake]) -> Textual content {
  guard let group = group.first else { return Textual content("Unknown") }
  swap groupOption {
    case .time:
      return Textual content(group.time.formatted(date: .numeric, time: .omitted))
    case .magnitude:
      return Textual content("(group.magnitude)")
    case .none:
      return Textual content("All quakes")
  }
}

So after I return the overall @Question personal var quakes: [Quake] there may be an array returned with the information.

Utilizing the sorting included within the Apple check venture the quakes are sorted accurately.

As quickly as I attempt to add in grouping and type that knowledge returns clean arrays.

Is there one thing I am overlooking?



Supply hyperlink

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisment -
Google search engine

Most Popular

Recent Comments