Как правильно настроить перемещение ячеек в таблице?


#1

Коллеги добрый день!

задача пользователя расставить ячейки по порядку. (например ребенку)
ячейки перемещаем используя:

Код
override func viewDidLoad() {
    super.viewDidLoad()
    ...
    table.dragDelegate = self
    table.dropDelegate = self
    table.dragInteractionEnabled = true
    ...
}

func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
    return true
}
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
    usersChooseOrder.insert(usersChooseOrder.remove(at: sourceIndexPath.row), at: destinationIndexPath.row)
}
    
func tableView(_ tableView: UITableView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
    print("itemsForBeginning")
    return []
}
    
func tableView(_ tableView: UITableView, performDropWith coordinator: UITableViewDropCoordinator) {
    print("  coordinator")
}

В любой момент можно проверить правильность расстановки нажав кнопку “Готово” и правильные ячейки, которые на своем месте окрашиваются в зелёный.
Подскажите в какую сторону искать чтоб реализовать следующее:

  • зеленая ячейка должна закрепится на своем месте и не передвигаться больше, ни пальцем, ни из-за перемещения других ячеек. Т.е. если 5 переместить на место 2 под 4 то 2 должна уехать на место 6, а 4 остаться на месте.

А если 5 перемещаем на место 6 то 6 и 1 поднимаются выше а 5 получается над 4.

Буду рад любому намеку.

Благодарю!


Вопрос про жесты. Как двигать UITableViewCell вслед за UIPanGestureRecognizer
#2

Ух… это будет та еще логика, поломаете вы голову.
Сперва можно начать с простого, что бы запретить перетаскивание какой-либо ячейки, в методе canMoveRowAt делаете проверку, находится ли ячейка на своем месте и возвращаете результат, только обратный.

Всю остальную логику уже нужно будет делать в методе moveRowAt и после каждого переноса, проверять все ячейки (кроме той, которую переносили), смотреть какие на своих местах и на основе этого результата, делать дополнительные передвижения.


#3

Эта логика мне кажется у вас уже должна работать.


#4

Эта работает. Я для примера написал…
За подсказку благодарю! Когда есть направление куда двигаться уже много легче…
Не прощаюсь…


#5

Это вы уже работаете с darg&drop после 11 версии, там много чего добавили для автоматизации, поищите в доках, может что-то будет полезное.
я делал drag&drop между двумя collectionView, с поддержкой до 11 версии. там API немного примитивнее, но у меня и не было такой логики. было лишь блокировка перемещения из одной view в другую, но внутри своей, перемещать можно.


#6

Благодарю!
В продолжение темы:
есть две секции по 4 ячейки.


нужно из одной секции в другую перенести ячейку, и если перенес правильно - то ячейки должны как бы объединиться
т.е. если из верхней секции 1 перенесли в нижнюю на 1 то из верхней она стирается или скрывается а в нижней делается отметка что 1 угадана.

А если не на 1 то верхняя 1 улетает на свое место.

Проверка должна происходить при отпускании ячейки.

И еще раз Благодарю!


#7

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


#8

Есть такая вот функция:

   func tableView(_ tableView: UITableView, targetIndexPathForMoveFromRowAt sourceIndexPath: IndexPath, toProposedIndexPath proposedDestinationIndexPath: IndexPath) -> IndexPath {
        
        print(proposedDestinationIndexPath, "current ")

        return proposedDestinationIndexPath
    }

Она в реальном времени отражает IndexPath того места где находится ячейка когда я ее перемещаю. Т.е. она срабатывает во время движения. Думаю как-то нужно тут искать.