UITablevView seemingly exits Edit mode automatically

I have inherited an Objective-C code base with a nasty bug where a view controller has a tableview that is seemingly exiting edit mode.


Items are dragged from a view that is above the table and dropped onto the table, which adds them to the backing data store. When the items are dragged onto the table, reloadData is used to refresh the table with the added items. As a matter of fact, reloadData is used a lot sprinkled in the code which bothers me a bit since the table could be moving into edit and non-edit mode via various means.


The code sets the table view into edit mode when a button (labeled Edit) is pressed using the following code


[_tableView setEditing:YES animated:YES];


and when the button is pressed again (labeled Done), the table view is told to exit edit mode using


[_tableView setEditing:NO animated:NO];


While the table is in edit mode, rows can be reordered and deleted. When a row is deleted it is removed from the backing data store and


[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];


is called to update the table and when there are no more rows in the backing data store, reloadData is called on the table (although I am not sure why since the rows was just deleted from the table with the line above. The problem is that I can add then remove rows from the table view the first time just fine. After that, I drag items to the table view to build the list again. I put the table in edit mode and remove the first row. Once the row gets deleted (with the code directly above) and reloadData is called, the table exits edit mode, meaning that the red circles and reorder buttons go away and the table is out of edit mode.


I guess the bottom line is that the code isn't the best, it feels like spaghetti to me. I had an idea that I would like to observe isEditing of the UITableView instance to see when it is being set to NO. I may try that next to see if I can pinpoint when the tableview is being taken out of edit mode and what may be causing that to happen.


Any ideas why this might be happening would be greatly appreciated.

Accepted Reply

reloadData() clears a lot of things in the tableView.


What you could do to track the problem:

- before any call to reloadData, insert a print to test the 'editing' property of the tableView

- after it, test again


Doing so, you will find where the editing is turned off.


After this, you could :

- remove reloadData everywhere it is not needed

- replace with

- reloadRowsAtIndexPaths:withRowAnimation: or - reloadSections:withRowAnimation:


Could also be interested by this thread:

https://stackoverflow.com/questions/30998906/when-a-uitableviewcell-is-in-editing-mode-and-we-reload-the-uitableview-how-to


Note: if you have time, the best could be to rewrite the whole code, to get rid of spaghettis, as one problem may hide a lot of others…

Replies

reloadData() clears a lot of things in the tableView.


What you could do to track the problem:

- before any call to reloadData, insert a print to test the 'editing' property of the tableView

- after it, test again


Doing so, you will find where the editing is turned off.


After this, you could :

- remove reloadData everywhere it is not needed

- replace with

- reloadRowsAtIndexPaths:withRowAnimation: or - reloadSections:withRowAnimation:


Could also be interested by this thread:

https://stackoverflow.com/questions/30998906/when-a-uitableviewcell-is-in-editing-mode-and-we-reload-the-uitableview-how-to


Note: if you have time, the best could be to rewrite the whole code, to get rid of spaghettis, as one problem may hide a lot of others…

Thanks a bunch for this answer. After I posted this, I was reading about how reloadData effects a lot of things, so I put a bunch of NSLog statements in close proximity to the reloadData statements and still couldn't pin down where editing was being turned off. I am in favor of replacing the reloadData calls since I don't believe it necessary to do this as much as the code does, which is a lot. I am going to try that next.


As far as a rewrite, that's just not in the cards at this time due to time and budget constraints. We have a future project to convert this project to Swift, so there is hope I'll get back to it in the near future.


Thanks again!

I think it is the right approach:

- remove reloadData unless you understand it is needed to do so (if you added or removed cells for instance).

- or replace by more selective reload if you have a doubt.

Just a follow up. I scoured the code and found several duplicated lines of code that were being executed multiple times that changed the state of the tableview. Once I reduced those and refactored the reloading to reload the only section of the table, this issue cleared up.


Thanks!