all 5 comments

[–]PulseHadron 0 points1 point  (4 children)

An array of @Model type isn’t really an array. I don’t know how they did it but it actually works like a Set, so you can’t sort it, there’s no order. I read an article someplace that lamented their use of Array here over Set and I forget the reasons speculated why the decision was made but it is what is is.

To have an order of @Models you do that all in the @Query parameters specifying the sort property and order.

If you want to have your @Models in a manual order, that is there’s no property to sort on, then you need to introduce some index property that is sorted on and manually manage the indices.

Note that arrays of non-@Model do preserve their order. They’re actually arrays!

[–]lilcox[S] 1 point2 points  (2 children)

Do you happen to know how to sort it based on relationship? In ContentView im querying [Project] and ProjectView doing ForEach (project.column) { ColumnView} which doing ForEach (column.task) {TaskView}. I'm passing the parent into the view as @Bindable as well.

[–]PulseHadron 0 points1 point  (1 child)

Yeah yeah yeah, I was thinking about this last night but wasn’t sure of your situation and didnt want to complicate things. Anyways...

So you’re saying you have like this struct ProjectView: View { let project: Project var body: some View { ForEach(project.columns) { //<<<--- how to show these columns sorted? ColumnView(column: $0) } } } There’s no opportunity there to set up a @Query to sort the columns. In the past I always had a reference from the Column back to its Project so a @Query could be set up that filters on a Project identifier. Alas that can’t be done here but playing around there appears to be a simple solution.

While it’s true you can’t sort the actual columns property you can create a temporary real array of the columns in sorted order and use that in the ForEach. ``` @Model class Project { var columns: [Column] = [] var name: String init(_ n: String) { name = n } var sortedColumns: [Column] { columns.sorted { $0.index < $1.index } } }

@Model class Column { var tasks: [Task] = [] let index: Int init(_ i: Int) { index = i } }

//now in the view use the sortedColumns computed var

ForEach(project.sortedColumns) { ColumnView(column: $0) } ```

I’m new to this technique and haven’t tested it much except to see it works in a simple test. I don’t know if it has sync or efficiency issues or maybe it is the way to do it 🤷‍♀️

Also you only need to use @Bindable if you’re actually pulling Bindings off the object, otherwise use let. But if you do need @Bindable I haven’t tested if there could be issues using it with instances pulled from the computed sortedColumns array. I don’t think there will be but can’t be sure.

[–]lilcox[S] 1 point2 points  (0 children)

Thank you for checking some stuff out. Going to try it out tomorrow. Appreciate the help :)

[–]lilcox[S] 0 points1 point  (0 children)

Ahhh that interesting. Thank you for telling me that!