web-dev-qa-db-ja.com

UITableViewの行の並べ替えをセクションに制限する方法

私はこれに頭を打っていましたが、グーグルは何も見せていませんでした。私は最終的にそれを解決し、次の人のためにここに書き上げると思いました。

複数のセクションを持つUITableViewがあります。各セクションは同種ですが、テーブル全体は異種です。そのため、セクション内の行の並べ替えを許可したい場合がありますが、acrossセクションは許可しません。たぶん、1つのセクションだけを並べ替えたいと思うことさえあるかもしれません(私の場合)。私が見たように、UITableViewDataSourceDelegateで探している場合、セクション間で行を移動できるようになる時期についての通知は見つかりません。行の移動を開始すると(これで問題ありません)、すでに行を移動してから内部のものと同期する機会が得られます。役に立たない。

それでは、セクション間の再注文をどのように防ぐことができますか?

私が別の回答として行ったことを投稿し、他の誰かがさらに良い回答を投稿できるように公開しておきます!

116
philsquared

この実装は、Philの答えのように元のセクションの外での並べ替えを防止しますが、ドラッグが開始した場所ではなく、どこに行ったかに応じて、レコードをセクションの最初または最後の行にスナップします。

- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
  if (sourceIndexPath.section != proposedDestinationIndexPath.section) {
    NSInteger row = 0;
    if (sourceIndexPath.section < proposedDestinationIndexPath.section) {
      row = [tableView numberOfRowsInSection:sourceIndexPath.section] - 1;
    }
    return [NSIndexPath indexPathForRow:row inSection:sourceIndexPath.section];     
  }

  return proposedDestinationIndexPath;
}
178
Jason Harwig

本当に簡単です。

UITableViewDelegateには次のメソッドがあります。


tableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath:

これは、ユーザーが潜在的なドロップポイントにカーソルを合わせているときに呼び出されます。 「いいえ、そこにドロップしないでください!代わりにここにドロップしてください」と言う機会を得ます。提案されたものとは異なるインデックスパスを返すことができます。

セクションインデックスが一致するかどうかを確認するだけでした。彼らがその後素晴らしい場合は、提案されたパスを返します。そうでない場合は、ソースパスを返します。また、これにより、他のセクションの行がドラッグしても邪魔にならないようにできます。ドラッグした行は、元の位置に戻り、別のセクションに移動しようとします。


- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
    if( sourceIndexPath.section != proposedDestinationIndexPath.section )
    {
        return sourceIndexPath;
    }
    else
    {
        return proposedDestinationIndexPath;
    }
}
71
philsquared

Swifty Swift怠け者のためのジェイソンの答えのバージョン:

override func tableView(tableView: UITableView, targetIndexPathForMoveFromRowAtIndexPath sourceIndexPath: NSIndexPath, toProposedIndexPath proposedDestinationIndexPath: NSIndexPath) -> NSIndexPath {
    if sourceIndexPath.section != proposedDestinationIndexPath.section {
        var row = 0
        if sourceIndexPath.section < proposedDestinationIndexPath.section {
            row = self.tableView(tableView, numberOfRowsInSection: sourceIndexPath.section) - 1
        }
        return NSIndexPath(forRow: row, inSection: sourceIndexPath.section)
    }
    return proposedDestinationIndexPath
}
22

以下の方法を使用して、セクション間の行の移動を防ぐことができます。セクション間の移動を許可しないでください。セクション内の特定の行の移動を制御することもできます。例:セクションの最後の行。

以下に例を示します。

- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath {

    // Do not allow any movement between section
    if ( sourceIndexPath.section != proposedDestinationIndexPath.section) {
        return sourceIndexPath;
    }
    // You can even control the movement of specific row within a section. e.g last row in a     Section

    // Check if we have selected the last row in section
    if (sourceIndexPath.row < sourceIndexPath.length) {
        return proposedDestinationIndexPath;
    } 
    else {
        return sourceIndexPath;
    }
}
7
Andy

スウィフト3:

override func tableView(_ tableView: UITableView, targetIndexPathForMoveFromRowAt sourceIndexPath: IndexPath, toProposedIndexPath proposedDestinationIndexPath: IndexPath) -> IndexPath {
    if sourceIndexPath.section != proposedDestinationIndexPath.section {
        var row = 0
        if sourceIndexPath.section < proposedDestinationIndexPath.section {
            row = self.tableView(tableView, numberOfRowsInSection: sourceIndexPath.section) - 1
        }
        return IndexPath(row: row, section: sourceIndexPath.section)
    }
    return proposedDestinationIndexPath
}
6
Henry

@Jason Harwigよりも、以下のコードは正しく機能します。

- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
    {
      if (sourceIndexPath.section != proposedDestinationIndexPath.section) {
        NSInteger row = 0;
        if (sourceIndexPath.section < proposedDestinationIndexPath.section) {
          row = [tableView numberOfRowsInSection:sourceIndexPath.section] - 1;
        }
        return [NSIndexPath indexPathForRow:row inSection:sourceIndexPath.section];     
      }

      return proposedDestinationIndexPath;
    }
4
Bkillnest

セクション間で位置を変更しない場合Swift

override func collectionView(_ collectionView: UICollectionView, targetIndexPathForMoveFromItemAt originalIndexPath: IndexPath, toProposedIndexPath proposedIndexPath: IndexPath) -> IndexPath {
    if originalIndexPath.section != proposedIndexPath.section
    {
        return originalIndexPath
    }
    else
    {
        return proposedIndexPath
    }
}
0
ayalcin