I have an editable UITableView. While my user is re-arranging the cells, I want to be able to update the tableview because I get a funny situation when I re-arrange the bottom cell and insert it into the middle. It create an unwanted effect because the bottom row is rounded and the middle row should not be. How can I prevent this from happening?

To achieve this look I had to set the backgroundView of each UITableViewCell. The top and bottom ones are using a separate image than ones in the middle.
UPDATED:
I am not sure if I am missing any cases, because the images still get messed up when re-ordering.
for (NSIndexPath* visibleIndexPath in tableView.indexPathsForVisibleRows) {
UITableViewCell* cell = [tableView cellForRowAtIndexPath:visibleIndexPath];
//Top moving to middle rows
if (sourceIndexPath.row == 0 && proposedDestinationIndexPath.row != sectionRows - 1) {
((UIImageView *)cell.backgroundView).image = [UIImage imageNamed:@"tablemiddle55@2x.png"];
}
//Top moving to bottom
else if (sourceIndexPath.row == 0 && proposedDestinationIndexPath.row == sectionRows - 1) {
((UIImageView *)cell.backgroundView).image = [UIImage imageNamed:@"tablebottom55@2x.png"];
}
//Top moving to top
else if (sourceIndexPath.row == 0 && proposedDestinationIndexPath.row == 0) {
((UIImageView *)cell.backgroundView).image = [UIImage imageNamed:@"tabletop55@2x.png"];
}
//Middle moving to top
else if (sourceIndexPath.row != 0 && sourceIndexPath.row != sectionRows -1 && proposedDestinationIndexPath.row == 0)
{
((UIImageView *)cell.backgroundView).image = [UIImage imageNamed:@"tabletop55@2x.png"];
}
//Middle moving to bottom
else if (sourceIndexPath.row != 0 && sourceIndexPath.row != sectionRows -1 && proposedDestinationIndexPath.row == sectionRows - 1)
{
((UIImageView *)cell.backgroundView).image = [UIImage imageNamed:@"tablebottom55@2x.png"];
}
//Middle moving to middle
else if (sourceIndexPath.row != 0 && sourceIndexPath.row != sectionRows -1 &&
proposedDestinationIndexPath.row != sectionRows -1 && proposedDestinationIndexPath.row !=0)
{
((UIImageView *)cell.backgroundView).image = [UIImage imageNamed:@"tablemiddle55@2x.png"];
}
//Bottom moving to top
else if (sourceIndexPath.row == sectionRows - 1 && proposedDestinationIndexPath.row == 0)
{
((UIImageView *)cell.backgroundView).image = [UIImage imageNamed:@"tabletop@2x.png"];
}
//Bottom moving to middle
else if (sourceIndexPath.row == sectionRows - 1 && proposedDestinationIndexPath.row != 0 && proposedDestinationIndexPath.row != sectionRows - 1)
{
((UIImageView *)cell.backgroundView).image = [UIImage imageNamed:@"tablemiddle@2x.png"];
}
//Bottom moving to bottom
else if (sourceIndexPath.row == sectionRows - 1 && proposedDestinationIndexPath.row == sectionRows - 1)
{
((UIImageView *)cell.backgroundView).image = [UIImage imageNamed:@"tablebottom@2x.png"];
}
}
The code you posted is mostly wrong because of the
for {}. As it stands right now, you do something like “if the destination is such and the source is such, modify all the currently visible cells”. But anyway, this is not the main problem.I must say, I’ve played a lot of time with the method
tableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath:before even attempting to answer this question. Now I feel more confident to write it.For starters, using this method in conjunction with
tableView:cellForRowAtIndexPath:is not a good choice if you don’t know what’s happening. Simply put, even though the cells have shifted for the animation, the changes don’t really affect the tableView until the user stops dragging the cell.For example, let’s say that you have the cell at index 0 with the title
@"Hello", and the next cell with@"World", if you start dragging the first cell downwards, the animation will move the cell “Hello” one row upwards, but callingtableView:cellForRowAtIndexPathfor the row at index 0 will always return the “Hello” cell. The tableView is unaffected until the tableView reorder ends, everything else is just eye-candy.So, to answer your question, and to swap the images on the fly (as soon as the user moves the cell), you should do the following, for example, for the first row:
One the user drags the row 0 downwards, it tells the row at 1 to swap its background to the top, as he will become the new top row. Similar cases must be considered for the bottom row, or middle row becoming the first one. Also, the
for {}with the visible cells is not necessary in this case.Edit: Okay, I managed to make ALL the cases, it has some weird things here and there, but it works most of the time. The code here just changes the detailLabel to “First”/”Middle”/”Last”, but that should be easy to change with a Find&Replace.