Question

I have a UITableView where I want to be able to insert rows via the Insertion Control (green plus icon). (I originally had this working with the Add control on the navigation bar, but with 'back', 'add', and 'edit' controls I felt the navigation bar was a bit cluttered).

I got this working, but I don't like the way this interacts with the reorder control. My table only has one section; the insertion row will always be shown as the last row in the table, and it should not be reorderable.

I implemented canMoveRowAtIndexPath: to return false for the insertion control row, but this is only a partial solution. That removed the ability to drag the insertion row. However, nothing prevents a user from selecting a movable row and dragging it beneath the insertion controller row. (And if allowed, this crashes the app).

The workaround I've implemented is to check the to location in moveRowAtIndexPath:toIndexPath. If the destination location is below the insertion row, I do not perform the move, and I call [tableView reloadData] to redraw the previous table state. This works, but the appearance is clunky -- the row just snaps back to its previous position with no indication why.

Is this the correct behavior here -- or is there a more elegant solution? Ideally, I'd like the user to not be able to drag the row to an illegal location in the first place, but I'm not sure there is any mechanism to prevent it.

Was it helpful?

Solution

You need to implement the tableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath: delegate method. The implementation should return an appropriate index path based on whether the row can be targeted to the desired row or not.

OTHER TIPS

Here's the implementation:

// Don't allow dragging any moveable row below the insertion control
- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:   (NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
    int proposedRow = proposedDestinationIndexPath.row;
    int maxRow = [[[SADeckStore sharedStore] allDecks] count] - 1;
    if (proposedRow < maxRow)
        return proposedDestinationIndexPath;
    else
        return [NSIndexPath indexPathForRow:maxRow inSection:[proposedDestinationIndexPath section]];
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top