如何将UITableView行重新排序限制为一个部分

时间:2009-05-11 20:27:58

标签: ios iphone uitableview cocoa-touch

我在这个上面撞了我的头,谷歌什么也没出现。 我最终解决了这个问题,并认为我是为了下一个人而在这里写的。

您有UITableView个多个部分。每个部分都是同质的,但整体表格是异构的。因此,您可能希望允许对部分中的行进行重新排序,但不允许部分进行重新排序。也许你甚至只想要一个部分可以重新排序(这是我的情况)。 如果你像我一样在UITableViewDataSourceDelegate看,你将找不到关于何时让你在不同部分之间移动一行的通知。当它开始移动一行(这很好)时会得到一个(当它已经移动它时你得到一个)并且你有机会与你的内部资料同步。没用。

那么如何防止各部门之间的重新订单?

我会将我所做的作为单独的答案发布,让其他人发布更好的答案!

7 个答案:

答案 0 :(得分:172)

此实现将阻止在原始部分之外重新排序,例如Phil的答案,但它也会将记录捕捉到该部分的第一行或最后一行,具体取决于拖动的位置,而不是它开始的位置。 / p>

- (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;
}

答案 1 :(得分:66)

很简单,真的。

UITableViewDelegate的方法有:


tableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath:

当用户将鼠标悬停在潜在的丢弃点上时,会调用此方法。 你有机会说,“不!不要把它放在那里!把它放在这里”。您可以返回建议的索引路径。

我所做的只是检查部分索引是否匹配。如果他们做得那么好,请返回建议的路径。如果没有,返回源路径。 这也可以很好地防止其他部分中的行甚至在您拖动时移开 - 并且拖动的行将捕捉回原来的位置,您尝试将其移动到另一个部分。


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

答案 2 :(得分:21)

杰森的快速版本给你懒惰的答案:

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
}

答案 3 :(得分:7)

您可以使用以下方法阻止部分之间的行移动。 只是不允许在部分之间进行任何移动。 您甚至可以控制某个部分中特定行的移动。例如,一节中的最后一行。

以下是示例:

- (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;
    }
}

答案 4 :(得分:4)

比@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;
    }

答案 5 :(得分:2)

斯威夫特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 :(得分:0)

不改变 Swift3

部分之间的位置
override func collectionView(_ collectionView: UICollectionView, targetIndexPathForMoveFromItemAt originalIndexPath: IndexPath, toProposedIndexPath proposedIndexPath: IndexPath) -> IndexPath {
    if originalIndexPath.section != proposedIndexPath.section
    {
        return originalIndexPath
    }
    else
    {
        return proposedIndexPath
    }
}