WWDC24 SALE: Save 50% on all my Swift books and bundles! >>

SOLVED: Move rows in a list is not working

Forums > SwiftUI

Hi everyone!

I was follow this tutorial and everything seems to be working well, the rows move correctly. But every time I leave this View and re-enter, the rows are arranged in the original order.

I don't know if the problem is about how the ForEach sorts the list or if the array comes from CoreData sorting by date.

Any idea? Thanks!

Here's the code:

@Environment(\.managedObjectContext) var viewContext
@ObservedObject var meeting: Meeting

ForEach(meeting.attendeesArray) { topic in
      HStack {
  .onDelete { index in
      vm.delete(at: index, meeting: meeting)
  .onMove(perform: move)
func move(from source: IndexSet, to destination: Int) {
    meeting.attendeesArray.move(fromOffsets: source, toOffset: destination)

CoreData Meeting entity:

@NSManaged public var title: String?
@NSManaged public var attendees: NSSet?

public var attendeesArray: [Ateendee] {
    let attendeeSet = attendees as? Set<Attendee> ?? []
    return attendeeSet.sorted { $0.attendeeDate < $1.attendeeDate }


This is because you don't save the new order. You need an additional property which stores the order. Everytime you sort the order after attendeeDate and the attendeeDate is not changed when you change the order.


Hi @Hatsushira, thank you for your answer!

You need an additional property which stores the order

And how is the best way to archived this? Because I have tried assigning a new date to attendeeDate at the time of changing the order but it has not worked. Any ideas?

Again, thanks.


You could add an Integer attribute to your entity. Everytime you add a record you can set this value to record count + 1. Then when you move, you have to set the order of the moved object to the new index and you have to set all other orders which are below to currentValue + 1. In your attendeesArray sort after order. When you use attendeeDate you would need to set the date to a value between the record before and the record after to keep the order. Which probably isn't what you want because this attribute stores a specific date and should not be used to keep track of the order.


I've finally been able to do it! Thank you very much @Hatsushira!!

I leave the code below in case it can be useful to someone.

I had to update the entity in CoreData with a new "order" attribute:

@NSManaged public var title: String?
@NSManaged public var attendees: NSSet?
@NSManaged public var order: Int16

Then the method updated:

private func move(from source: IndexSet, to destination: Int) {

        var revisedAttendees = meeting.attendeesArray

        revisedAttendees.move(fromOffsets: source, toOffset: destination )

        for reverseIndex in stride( from: revisedAttendees.count - 1, through: 0, by: -1 ) {
            revisedAttendees[ reverseIndex ].order =
                Int16( reverseIndex )


Save 50% in my WWDC sale.

SAVE 50% To celebrate WWDC24, all our books and bundles are half price, so you can take your Swift knowledge further without spending big! Get the Swift Power Pack to build your iOS career faster, get the Swift Platform Pack to builds apps for macOS, watchOS, and beyond, or get the Swift Plus Pack to learn advanced design patterns, testing skills, and more.

Save 50% on all our books and bundles!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

Unknown user

You are not logged in

Log in or create account

Link copied to your pasteboard.