|
Hey all, I'm just finished up the beginner SwiftData tutorial and was experimenting with adding a .move modifier to the "sights". Do I need to add a seperate SortDescriptor and initializer for the sights? Is it possible to have seperate SortDescriptors for just the sights of each destination? When I drag/drop the sight to move/re-order a sight, it just resets back to ordering it by name. Here is my EditSightView:
|
|
Hi @rheek! I doubt it is feasible in this context. By context I mean, in your case you are using manual sorting by moving items around. As they say SwiftData rests on shoulders of Core Data, and in Core Data collections are stored in Set data type, meaning you cannot store it in partuculare order. I know, we all see Arrays in @Relationships and @Query but Core Data stores them as Set data type, by obvious reason it is more efficient. Well, maybe my deduction is wrong and community can help us in here. As for filter, I suppose there is a way to filter that as for example I managed to make your manual sort to work in subview. But in below example I simply copy sights to local variable and use that for that particular view, but you can notice that as soon as you go back to previous view and return your manual sorting is gone. Definitely, you can apply some filter even to this local variable. But again as data behind it is Set you cannot sort that in the same way as you can in Array.
|
|
Thanks for the reply!. After reading through your reply, I'm assuming that the way to solve this issue is to add an attruibute l"sortvalue", and then each time a .move function happens, map the entire customSortSghts array with the existing order then replace the entire array, forcing a refresh. I really don't remember how to do that, but I'll go back through some of the other courses to get a refresher and see if I can get that to work. Thanks again! |
|
I finally got it working, but I'm not sure the solution is the most elegant or clean. I added a new attribute to SIght called sortOrder:
Now I can store a custom sortorder. I also added a function at the end to loop through the currently displayed sight and renumber the order starting at 0 and then replace that destination's Sites with the re-ordered temporarty array. I'd love anyone's input on more efficient ways of writing out this function or any other critique. When re-launching the data displays correctly, and I can't find any functional issues that cauase the code to function incorrectly. (I also added in a display text to show the "custom sort order".)
|
|
Hello. I am running into the exact same problem. Also curious if there is a more elegant solution. |
|
hi, @rheek found a basic solution in which you store a i've used this myself (see my ShoppingList project, when aranging the order of Locations), and although it's somewhat inefficient, it gets the job done especially when the number of models you are arranging by moving them about in a list is somewhat small -- don't do this for a few thousand items! there are two alternatives you can look at. (1) if you make @rheek's it's quite efficient: only the sort order of the item moved needs to be rewritten. (2) in a slightly different direction, store a separate item in SwiftData/Core Data whose only purpose is to track the order of the items you present in the list. show items in a list in the order specified by this array. it's easy to do in SwiftData by keeping an array of, say, item UUIDs and using that array and indirection to lay out the list. (in Core Data, but you'll need to specify a value transformer for this code seems to work:
hope this helps, DMG |
|
I put together a sample project illustrating the cleanest workaround I could come up. Rather than paste all the code here you can see it all in a repo I made: https://github.com/hekuli/swiftdata-test/tree/main I'd be thrilled to get any feedback on how this could be improved. |
|
@rheek In my opinion you got to the root of the problem when you added the sortOrder property as an Int, but most of the rest was not needed...or at least I did not need them. Approx 5 minutes of reading the initial response and updating my code got me the correct reults very quickly. Like Delaware MathGuy, I also created a like and similar project where I like to list records with the latest at the top; or in your case ...order:.reverse. My default query for the item table is on itemNum,order:.reverse. itemNum ==> sortOrder. As a result, all I needed to do was add the custom sort order declaration and to the init() ` // Create local variable to store your sights from a particular destination @State private var customSortSights: [Sight]
Caveat...I am leveraging MANY years of Oracle Relational DB programming to get similar results out of SQLite/SwiftData. BTW...Mark Moeykens covers refreshing views easily in Mastering SwiftData |
|
Late to this but was looking to solve a similar problem. I added a
When I create a new item, I set |
SPONSORED Take the pain out of configuring and testing your paywalls. RevenueCat's Paywalls allow you to remotely configure your entire paywall view without any code changes or app updates.
Sponsor Hacking with Swift and reach the world's largest Swift community!
You need to create an account or log in to reply.
All interactions here are governed by our code of conduct.
Link copied to your pasteboard.