iOS reordering a UITableView - ios

I have a UITableView that reads data from a sql db.
When i reorder the data it only changes the top and bottom ones
Dragging 1 from top to bottom
When i let it go at 5 it only switches the top and bottom ones.
I am using the following
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
[myStringsArray exchangeObjectAtIndex:fromIndexPath.row withObjectAtIndex:toIndexPath.row];
}
How can i reorder the list? So it'll be 2,3,4,5,1 and not 5,2,3,4,1

Exchange is not a proper way to do it you should use this.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
id buffer = [myStringsArray objectAtIndex:fromIndexPath.row];
[myStringsArray removeObjectAtIndex:fromIndexPath.row];
[myStringsArray insertObject:buffer atIndex:toIndexPath.row];
}
Edited to match comment below.

Related

How do I properly reload a UITableView after reordering or deleting a row?

I have a UITableView whose cells also display their row number. Obviously, after reordering or deleting a row I have to also update potentially all row number labels.
I guess, there must be a better way to achieve this without interfering with the associated animations for deleting a row than
- (void)tableView:(UITableView *)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.tableView performSelector:#selector(reloadData) withObject:nil afterDelay:0.6];
}
and for reordering a row
-(void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
{
...
[self.tableView performSelectorOnMainThread:#selector(reloadData) withObject:nil waitUntilDone:NO];
}
must it not?

Preventing a specific move in moveRowAtIndexPath

I have a UITableView in my Objective-C iOS app, of which I need to have a specific cell displaying information while all the others cells should move freely.
With my current code, I prevented said cell to be moved by other cells, but it is still possible to move underneath it.
This cell is not part of my Data model so I really need to keep this in the controller layer.
In other words, I'm looking for a way to prevent the default behaviour.
Below is my current code:
-(void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
{
if (destinationIndexPath.row == [tableView numberOfRowsInSection:0]-2) {
//prevent the move
}
else {
[[BNRItemStore sharedStore] moveItemAtIndex:sourceIndexPath.row toIndex:destinationIndexPath.row];
}
}
What should I change in order to obtain the desired functionality?
Did you try to implement this delegate method?
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath;
Use targetIndexPathForMoveFromRowAtIndexPath as below,
// Allows customization of the target row for a particular row as it is being moved/reordered
- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath {
if( proposedDestinationIndexPath is ok ) {
return proposedDestinationIndexPath;
} else {
return sourceIndexPath;
}
}

UITableView doesn't show bars to move the cells

I tried to implement this method in order to be able to move the cells in my Tableview.
And everything runs well but the bars aren't shown and I'm not able to move the cells.
- (void)moveRowAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath {
[[HPPossessionStore defaultStore] movePossessionAtIndex:[indexPath row] toIndex:[newIndexPath row]];
}
What do I have to do to make it work?
Add below delegate method as well.
- (BOOL)tableView:(UITableView *)tableView
canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
This solved my problem, although I have no idea why. If someone could explain it I would be very thankful.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
[[HPPossessionStore defaultStore] movePossessionAtIndex:[fromIndexPath row] toIndex:[toIndexPath row]];
}
It is explained in more detail here: https://stackoverflow.com/a/20786785/2310837

Reorder/move UITableViewCell but moves back

I want to implement a method to be able to reorder the rows of a tableview.
In each section i only have one row. When the editing-state of the tableview is enabled, the move indicators appear as expacted. But when i drag one of the cell to another position, the cell immediatly (after approximatly 1 s) pops back to the original position. This is weired to me, because i implemented such a reorder functionality already. The difference between those two projects are that the new project implements a bunch of gesture recognizers (eg UILongPressGestureRecognizer, UIPanGestureRecognizer, UIPinchGestureRecognizer,..). I already thought about the possibility that one of the gesture recognizers is blocking the drag action of the tableviewcell but its not.
You can see the code below:
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath {
//return [NSIndexPath indexPathForRow:0 inSection:3];
return nil;
}
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath {
NSLog(#"%#", destinationIndexPath);
}
Can anyone help me pls?
UPDATE:
I found out that the moved tableviewcell is beeing moved to the original destination index path. Does that indicate, that a reloadData on the table view has happened?
2nd UPDATE:
Because it was menthioned by Andrei Shender why i return nil in the tableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath: method you can find my updated code below.
- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath {
return proposedDestinationIndexPath;
//for testing purpose only
//return nil;
}
Btw when changing my code, i found out, that this method never gets called. Regarding to Apples documents about reordering tableviewcells it should get called.
Thanks to this posting I figured out, what the problem was. Combining a UIPanGestureRecognizer and a UITableView with the reorder/move funcationality is a tricky thing.
When i edit the tableview, i remove the gesture recognizer (of the viewcontroller's view) and when the editing is disabled again, i add the gesture recognizer again.
Be sure to update your data source in the method :
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath

UITableView reorder with tap within table

A question for those who have used a UITableView in the past
I am currently using a UITableView in edit mode and I have the following data source / delegate methods implemented
(void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
//which tells me where the cell has been moved to
(NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
//which tells me where it may be moved
What I want to achieve:
when I pick a cell and reorder it, the cell should move up and down in the table view only while the finger is within the table view. Which means if I start from within the table view and move outside it, the cell should snap back in position and not let me reorder the cell.
The problem is that there is no way to find out (that I know of) where my finger is while the reorder is being performed. If I can find out where the finger is then it might be possible to achieve this.
Any ideas?
Take a look at the (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath function. HTH.

Resources