テーブルセルの並び替え

テーブルセルの並び替えをするときは、UITableViewControllerに以下のメソッドを実装します。セクションをまたいだ移動を禁止するなど、移動可能な範囲を制御することも可能です。
# 並び替え以外の箇所は省略します。

- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
  if (移動したいもの) return YES;
  else return NO;
}

移動可能なセルを決めます。"return YES;"したものが移動可能になります。

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
  // 移動後の後処理
}

このメソッドを実装すると、実際に移動できるようになります。移動後に処理することをここに記述します。

- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath {
  if (sourceIndexPath.section == proposedDestinationIndexPath.section) {
    // 移動後のセクションが同じセクションならそのまま
    return [NSIndexPath indexPathForRow:proposedDestinationIndexPath.row inSection:proposedDestinationIndexPath.section];
  } else if (sourceIndexPath.section > proposedDestinationIndexPath.section) {
    // 移動後のセクションのほうが上(小さい)なら、元のセクションの一番上(0)にする
    return [NSIndexPath indexPathForRow:0 inSection:sourceIndexPath.section];
  } else {
    // 移動後のセクションのほうが下(大きい)なら、元のセクションの一番下にする
    return [NSIndexPath indexPathForRow:元のセクションの一番下 inSection:sourceIndexPath.section];
}

どこにでも移動可能にするなら、このメソッドは実装しなくてOKです。上の例では、セクションをまたいだ移動を禁止しています。