Как ограничить переупорядочение строк UITableView в разделе - PullRequest
114 голосов
/ 12 мая 2009

Я ударился головой об этом, и Google ничего не обнаружил. В конце концов я решил это и решил написать здесь ради следующего человека.

У вас есть UITableView с несколькими разделами. Каждый раздел однороден, но таблица в целом неоднородна. Таким образом, вы можете разрешить изменение порядка строк в разделе, но не в разделах. Может быть, вы даже хотите, чтобы один раздел был переставляем вообще (это был мой случай). Если вы смотрите, как я, на UITableViewDataSourceDelegate, вы не найдете уведомления о том, когда он собирается переместить строку между разделами. Вы получаете один, когда он начинает перемещать строку (что нормально), и один, когда он уже перемещен, и вы получаете возможность синхронизировать с вашими внутренними материалами. Не полезно.

Так, как вы можете предотвратить повторные заказы между разделами?

Я опубликую то, что я сделал, в качестве отдельного ответа, оставив открытым для кого-то еще возможность опубликовать еще лучший ответ!

Ответы [ 7 ]

173 голосов
/ 12 мая 2009

Эта реализация предотвратит переупорядочение за пределами исходного раздела, как ответ Фила, но также привязывает запись к первой или последней строке раздела, в зависимости от того, куда было перетащено, а не от того, где оно началось. 1001 *

- (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;
}
66 голосов
/ 12 мая 2009

Достаточно просто, правда.

UITableViewDelegate имеет метод:


tableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath:

Это вызывается, когда пользователь наводит курсор на потенциальную точку сброса. У вас есть возможность сказать: «Нет! Не бросайте это туда! Вместо этого бросьте это сюда». Вы можете вернуть другой путь индекса к предложенному.

Все, что я сделал, это проверил, совпадают ли индексы секций. Если у них все получится, верните предложенный путь. если нет, верните исходный путь. Это также прекрасно предотвращает перемещение строк в других разделах даже при перемещении - и перетаскиваемый ряд вернется в исходное положение, если вы попытаетесь переместить его в другой раздел.


- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
    if( sourceIndexPath.section != proposedDestinationIndexPath.section )
    {
        return sourceIndexPath;
    }
    else
    {
        return proposedDestinationIndexPath;
    }
}
21 голосов
/ 03 марта 2015

Быстрая и быстрая версия ответа Джейсона для вас, ленивые люди:

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
}
7 голосов
/ 27 июля 2014

Вы можете предотвратить перемещение строк между сечениями, используя метод ниже. Только не допускайте никаких движений между секциями. Вы даже можете контролировать движение определенной строки в разделе. например, последняя строка в разделе.

Вот пример:

- (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 голосов
/ 20 февраля 2013

Чем @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;
    }
2 голосов
/ 23 июля 2017

Swift 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
}
0 голосов
/ 14 августа 2017

Для неизменного положения между секциями Swift3

override func collectionView(_ collectionView: UICollectionView, targetIndexPathForMoveFromItemAt originalIndexPath: IndexPath, toProposedIndexPath proposedIndexPath: IndexPath) -> IndexPath {
    if originalIndexPath.section != proposedIndexPath.section
    {
        return originalIndexPath
    }
    else
    {
        return proposedIndexPath
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...