iOSの公式ドキュメント翻訳のためのテーブルビュープログラミングガイド



Table View Programming Guide



テーブルビューには、編集モードと通常の(選択)モードがあります。テーブルビューが編集モードになると、その行に関連付けられている編集および並べ替えコントロールが表示されます。並べ替えコントロールを使用すると、ユーザーは行をテーブル内の別の場所に移動できます。図8-1に示すように、並べ替えコントロールが行の右側に表示されます。

テーブルビューには、編集モードと通常の(選択)モードがあります。テーブルビューが編集モードに入ると、その行に関連付けられている編集および並べ替えコントロールが表示されます。並べ替えコントロールを使用すると、ユーザーは行をテーブル内の別の位置に移動できます。図8-1に示すように、並べ替えコントロールが行の右側に表示されます。



図8-1行の並べ替え

テーブルビューが編集モードになり、ユーザーが並べ替えコントロールをドラッグすると、テーブルビューは一連のメッセージをデータソースに送信して委任しますが、これらのメソッドを実装している場合に限ります。これらのメソッドを使用すると、データソースとデリゲートは、実際の移動操作を実行するために、行を移動できるかどうか、およびどこに移動できるかを制限できます。次のセクションでは、テーブルビューで行を移動する方法を示します。



テーブルビューが編集モードに入り、ユーザーが並べ替えコントロールをドラッグすると、テーブルビューは一連のメッセージをデータソースとエージェントに送信しますが、これらのメソッドを実装している場合に限ります。これらのメソッドを使用すると、データソースとエージェントは、行と列の移動位置を制限して、実際の移動操作を実行できます。次のセクションでは、テーブルビューで行を移動する方法を示します。

行が再配置されたときに何が起こるか

テーブルビューは、setEditing:animated:メッセージを受信すると編集モードになります。これは通常、ユーザーがナビゲーションバーの[編集]ボタンをタップしたときに発生しますが、必要に応じて独自のコントロールを実装できます。編集モードでは、テーブルビューに、デリゲートが各行に割り当てた並べ替えおよび編集コントロールが表示されます。デリゲートは、UITableViewCellオブジェクトのshowsReorderControlプロパティをYESに設定することにより、tableView:cellForRowAtIndexPath:のコントロールを割り当てます。並べ替えコントロールを表示するには、データソースがtableView:moveRowAtIndexPath:toIndexPath:メソッドを実装して並べ替えをサポートしている必要があります。

テーブルビューは、setEditing:animated:メッセージを受信すると編集モードになります。これは通常、ユーザーがナビゲーションバーの編集ボタンをクリックしたときに発生しますが、必要に応じて、独自のコントロールを実装できます。編集モードでは、テーブルビューに、各行に委任された並べ替えおよび編集コントロールが表示されます。 UITableViewCellオブジェクトのshowsReorderControlプロパティをYESに設定して、tableView:cellForRowAtIndexPath:のコントロールを委任し、コントロールtableView:cellForRowAtIndexPath:を割り当てます。並べ替えコントロールを表示するには、データソースがtableView:moveRowAtIndexPath:toIndexPath:メソッドを実装して並べ替えをサポートしている必要があります。



注:UIViewControllerオブジェクトがテーブルビューを管理している場合、[編集]ボタンをタップすると、setEditing:animated:messageを自動的に受信します。 UIViewControllerのサブクラスであるUITableViewControllerは、このメソッドを実装してボタンの状態を更新し、テーブルビューのバージョンのメソッドを呼び出します。 UIViewControllerを使用してテーブルビューを管理している場合は、同じ動作を実装する必要があります。

注:UIViewControllerオブジェクトがテーブルビューを管理している場合、[編集]ボタンがクリックされると、setEditing:animated:メッセージが自動的に受信されます。 UITableViewControllerは、UIViewControllerのサブクラスであり、このメソッドを実装してボタンの状態を更新し、テーブルビューのメソッドバージョンを呼び出します。 UIViewControllerを使用してテーブルビューを管理する場合は、同じ動作を実装する必要があります。

テーブルビューがsetEditing:animated:を受信すると、表示されている各行のUITableViewCellオブジェクトに同じメッセージを送信します。次に、図8-2の図に示すように、一連のメッセージをデータソースとデリゲート(メソッドを実装している場合)に送信します。

テーブルビューがsetEditing:animated:を受信すると、表示されている各行のUITableViewCellオブジェクトに同じメッセージを送信します。次に、図8-2に示すように、一連のメッセージをデータソースとエージェント(これらのメソッドを実装している場合)に送信します。

図8-2テーブルビューで行を並べ替えるための呼び出しシーケンス

テーブルビューがsetEditing:animated:メッセージを受信すると、表示されている行に対応するセルオブジェクトに同じメッセージを再送信します。その後のメッセージの順序は次のとおりです。

テーブルビューがsetEditing:animated:メッセージを受信すると、表示されている行に対応するセルオブジェクトに同じメッセージを再送信します。その後のメッセージシーケンスは次のとおりです。

  1. テーブルビューは、tableView:canMoveRowAtIndexPath:メッセージをデータソースに送信します(メソッドを実装している場合)。この方法では、デリゲートは、特定の行を並べ替えコントロールの表示から選択的に除外できます。
  2. ユーザーは、並べ替えコントロールを使用して行をテーブルビューの上下にドラッグします。ドラッグされた行がテーブルビューの一部にカーソルを合わせると、下にある行が下にスライドして、宛先がどこにあるかが示されます。
  3. ドラッグされた行が宛先の上にあるたびに、テーブルビューはtableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath:をそのデリゲートに送信します(メソッドを実装している場合)。この方法では、デリゲートはドラッグされた行の現在の宛先を拒否し、別の宛先を指定できます。
  4. テーブルビューは、tableView:moveRowAtIndexPath:toIndexPath:をデータソースに送信します(メソッドを実装している場合)。このメソッドでは、データソースは、テーブルビューのアイテムのソースであるデータモデル配列を更新し、アイテムを配列内の別の場所に移動します。

  5. テーブルビューは、tableView:canMoveRowAtIndexPath:メッセージをデータソースに送信します(このメソッドを実装している場合)。この方法では、プリンシパルは、並べ替え制御を表示する特定の行を選択的に除外できます。

  6. ユーザーは、テーブルビューの並べ替えコントロールを介して行を上下にドラッグします。ドラッグした行がテーブルビューの一部にカーソルを合わせると、下にある行が下にスライドして目的の場所が表示されます。
  7. ドラッグされている行がターゲットを超えると、テーブルビューはtableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath:をデリゲートに送信します(このメソッドを実装している場合)。この方法では、デリゲートはドラッグされた行の現在の宛先を拒否し、代替目標を指定できます。
  8. テーブルビューは、tableView:moveRowAtIndexPath:toIndexPath:をデータソースに送信します(このメソッドを実装している場合)。このメソッドでは、データソースは、テーブルビューアイテムのソースであるデータモデル配列を更新し、アイテムを配列内の別の場所に移動します。

行の移動の例

このセクションでは、「行が再配置されたときに何が起こるか」に列挙されている並べ替え手順を示すサンプルコードについてコメントします。リスト8-1は、テーブルビューの最初の行を並べ替えから除外するtableView:canMoveRowAtIndexPath:の実装を示しています(この行には並べ替えコントロールがありません)。

このセクションでは、行を再配置するときに発生する並べ替え手順を示すサンプルコードをいくつか確認します。リスト8-1は、tableView:canMoveRowAtIndexPathを示しています。tableView:canMoveRowAtIndexPathの実装:テーブルビューの最初の行は並べ替えから除外されます(行には並べ替えコントロールがありません)。

リスト8-1 行を再配置から除外する

- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.row == 0) // Don't move the first row return NO return YES }

ユーザーが行のドラッグを終了すると、テーブルビューの宛先にスライドし、tableView:moveRowAtIndexPath:toIndexPath:をデータソースに送信します。リスト8-2は、このメソッドの実装を示しています。

ユーザーが行のドラッグを終了すると、テーブルビューのターゲット位置にスライドし、tableView:moveRowAtIndexPath:toIndexPath:をターゲットデータソースに送信します。リスト8-2は、このメソッドの実装を示しています。

リスト8-2 再配置された行のデータモデル配列を更新する

- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath { NSString *stringToMove = [self.reorderingRows objectAtIndex:sourceIndexPath.row] [self.reorderingRows removeObjectAtIndex:sourceIndexPath.row] [self.reorderingRows insertObject:stringToMove atIndex:destinationIndexPath.row] }

デリゲートは、tableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath:メソッドを実装することにより、提案された宛先を別の行に移動するために再ターゲットすることもできます。次の例では、行を独自のグループ内での再配置に制限し、グループの最後の行(アイテムの追加プレースホルダー用に予約されている)への移動を防ぎます。

tableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath:メソッドを実装することにより、エージェントは提案されたターゲットを別の行に移動することもできます。次の例では、行をそれ自体のグループ内の再配置に制限し、グループの最後の行への移動を防ぎます(アイテムのプレースホルダーを追加するために予約されています)。

リスト8-3 移動操作の宛先行を再ターゲットする

- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath { NSDictionary *section = [data objectAtIndex:sourceIndexPath.section] NSUInteger sectionCount = [[section valueForKey:@'content'] count] if (sourceIndexPath.section != proposedDestinationIndexPath.section) { NSUInteger rowInSourceSection = (sourceIndexPath.section > proposedDestinationIndexPath.section) ? 0 : sectionCount - 1 return [NSIndexPath indexPathForRow:rowInSourceSection inSection:sourceIndexPath.section] } else if (proposedDestinationIndexPath.row >= sectionCount) { return [NSIndexPath indexPathForRow:sectionCount - 1 inSection:sourceIndexPath.section] } // Allow the proposed destination. return proposedDestinationIndexPath }