0
votes

I am new on learning the Apple Book named APP Development with Swift. And I found a confused point about the Re-ordering the tableView, which was written by Apple Book.

Code is as below: Emoji is a struct, emojis is an var, emojis: [Emoji]

override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) {

    let movedEmoji = emojis.remove(at: fromIndexPath.row)
   
    emojis.insert(movedEmoji, at: to.row)
 
    tableView.reloadData()
}

What my confusion is: Even though I deleted the code inside the "override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath)", I can still use a button to enter the editing condition, then use the Re-order control to move the items up or down. Therefore, what is the usage of the code in the middle? I mean below code:

    let movedEmoji = emojis.remove(at: fromIndexPath.row)
   
    emojis.insert(movedEmoji, at: to.row)
 
    tableView.reloadData()

I think the code is just to move the item in the tableview, it's like first remove then insert, so is it unnecessary?

1
Do you understand that the emojis array act as a data source of the table view, and that it should be kept consistent with what's displayed in the table view? - Sweeper
@ficoman The emojis that you are referring is an array which is your data source so when you reorder the tablview the arrays should be updated as well. So, for example, you move your 4th row to 2nd row you need to change your emojis arrays positions as well. If you have a long list of emojis and you scroll up and came back to the position it will not reflect if you have updated your data source. - jogshardik
issue resolved. thanks everyone. - ficoman

1 Answers

0
votes

UITableViews only display part of its data source, the part that is visible on the screen. When new cells come into view, it asks its data source what cell it should display via cellForRowAt. For the table view to work as expected, the data source must know what the table view has been displaying, in order to answer that correctly.

This is why the table view must tell the data source that the user has moved one of its cells (via moveRowAt). If the data source didn't know that, and still thinks that nothing has been moved, the next time that part of the table view is displayed, the data source will answer with the old, unmoved data.

Example: Try deleting the code in moveRowAt. Add more emojis to the data source, i.e. emojis, so that you can scroll the table view quite far down. Run the app. Swap the first and second emojis. Scroll to the bottom and scroll back up again. This will cause the table view to ask the data source "what's the first cell I should display?" and "what's the second cell I should display?". Since the data source doesn't know the first two cell's have been swapped, you will see the two cells in their original order, as if your move has been undone.

This is why in moveRowAt, you need to move the elements in the emojis array as well. This way, emojis actually stores what's displayed on the screen.

As for the reloadData call, I think that's mainly to be safe. Just as the first two lines syncs the data source with the view, reloadData syncs the view with the data source, in case for some bizarre reason it is not.