views:

1869

answers:

2

Some help would be greatly appreciated here!

I have a custom UITableView cell, consisting of an image (green,orange or red) and two labels in different font sizes. The UITableView is driven by an NSMutableArray of objects.

The UITableView is split into three sections, with the first section containing all the cells with the red image, second section with the orange, third section with the green.

I have implemented the ability to rearrange the cells within UITableView, allowing the user to drag, say, an item with a red image from the red section into the orange section. This dragging works great, and the underlying data is updated correctly. I know this is the case because if I select the cell, I go to its detail view and the data is updated.

However, the UITableView does not update until I go to detail (or exit the app) and return! It also does update if I scroll the offending cell out of view and back into view again, so the array is clearly containing the correct data. I just can't trigger a view refresh!

I have tried the following after my code for changing the underlying data in moveRowAtIndexPath:

[self.tableView reloadData];

However this causes an exception. The Apple Language Reference in fact says that reloadData cannot be called when inserting, deleting or animating, which is of course what I'm doing. In addition, trying just to refresh the cell with

[self setNeedsDisplay];

doesn't work (although it doesn't crash either).

Any ideas on how I can refresh the UITableView? I can't find a afterMoveHasBeenCompleted: method or anything, so if I can't call reloadData during my moveRowAtIndexPath: method then where do I call it?!

+2  A: 

Take a look at the reference for UITableViewDelegate. If you assign your UITableView a delegate, you can use its methods to handle notifications that your table view has done something. You will probably use one of

tableView:didEndEditingRowAtIndexPath:
or
tableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath:
to accomplish this.

Tim
Unfortunately, tableView:didEndEditingRowAtIndexPath only seems to trigger after aborting the "side-swipe" action. Even if I was able to track the point at which editing ended (ie when the user clicks "done"), the images would still be wrong up until that point.The other method you suggest I am already using to allow drag and drop to only other sections. This has passed before I know whether I need to refresh or not.
h4xxr
+1  A: 

Got it!!

I discovered the solution was to put in a delay in the refresh code, which stopped it from crashing.

I put the reloadData call into a separate method:

- (void)refreshDisplay:(UITableView *)tableView {
[tableView reloadData]; }

and then called it with a 0.5 second delay:

[self performSelector:(@selector(refreshDisplay:)) withObject:(tableView) afterDelay:0.5];

And it didn't crash and instead refreshed! The 0.5 sec delay is barely noticeable and totally acceptable.

Hope this helps someone else!

Thanks

Phil

h4xxr
Or is this just a dirty hack? Is there an "animationComplete" method I can use instead?...
h4xxr
That seems to be the best way to do it, as per gpmoore's post on this Apple Developer thread: http://discussions.apple.com/thread.jspa?messageID=8450874
Tim
That's frustrating but very reassuring! Thanks!
h4xxr