Нет встроенной функциональности для достижения того, что вы хотите.Если я правильно понимаю, вы хотите свернуть целый ряд строк, а затем начать перетаскивать «заголовок» вокруг.Если вы хотите сделать это самостоятельно, я бы предложил начать с распознавателя панорамирования, который срабатывает на кнопке заголовка.
Жест должен быть относительно очевидным.После того, как он начинается в заголовке, вам нужно отслеживать позицию, используя locationIn
в табличном представлении.
Чтобы свернуть строки, все, что вам нужно сделать, это изменить ячейки табличного представления с соответствующей анимацией, например:
tableView.beginUpdates()
tableView.deleteSections([myIndexPath], with: .top) // Maybe experiment with animation type
// Modify whatever you need to correspond this change in the data source
tableView.endUpdates()
Поскольку вы будете удалять раздел, вы также будете удалять представление (заголовок), в котором есть распознаватель жестов.Это означает, что может быть лучше добавить жест непосредственно к табличному представлению или даже к его супервизору.Вам нужно будет заставить его срабатывать только при нажатии одной из этих кнопок в заголовках.Вы можете получить некоторую идею здесь об этом.Это изменение не затронет остальных.
На данный момент вам, вероятно, потребуется создать дополнительный вид, который представляет ваш стек секций и следует вашему пальцу.Это должно быть довольно просто, если вы добавите его в качестве подпредставления и управляете его центром с помощью распознавателя жестов панорамирования locationIn
в его суперпредставлении:
movableSectionView.center = panGestureRecognizer.location(in: movableSectionView.superview!)
Таким образом, до этого момента вы сможете получить раздел, которыйсворачивает все ячейки и может перетаскивать представление «стек секций».Теперь вам нужно проверить, где в табличном представлении ваш палец должен знать, куда уронить раздел.Это немного больно, но это можно сделать с помощью visibleCells
и tableView.indexPath(for: )
:
func indexPathForGestureRecognizer(_ recognizer: UIGestureRecognizer) -> IndexPath {
let coordinateView: UIView = tableView.superview! // This can actually be pretty much anything as long as it is in hierarchy
let y = recognizer.location(in: coordinateView).y
if let hitCell = tableView.visibleCells.first(where: { cell in
let frameInCoordinateView = cell.convert(cell.bounds, to: coordinateView)
return frameInCoordinateView.minY >= y && frameInCoordinateView.maxY <= y
}) {
// We have the cell at which the finger is. Retrieve the index path
return tableView.indexPath(for: hitCell) ?? IndexPath(row: 0, section: 0) // This should always succeed but just in case
} else {
// We may be out of bounds. That may be either too high which means above the table view otherwise too low
if recognizer.location(in: tableView).y < 0.0 {
return IndexPath(row: 0, section: 0)
} else {
guard tableView.numberOfSections > 0 else {
return IndexPath(row: 0, section: 0) // Nothing in the table view at all
}
let section = tableView.numberOfSections-1
return IndexPath(row: tableView.numberOfRows(inSection: section), section: section)
}
}
}
Как только распознаватель жестов завершится, вы можете использовать этот метод, чтобы получить раздел, в который вы помещаете свои элементы.Так что просто:
tableView.beginUpdates()
// Modify whatever you need to correspond this change in the data source
tableView.insertSections([indexPathForGestureRecognizer(panGestureRecognizer).section], with: .bottom)
tableView.endUpdates()
Этого должно быть достаточно для переупорядочения, но вы можете захотеть показать в табличном представлении, где находится перетаскиваемый раздел.Как наличие заполнителя в конце раздела, в который будет помещен стек.Это должно быть относительно просто, просто добавив, а затем переместив дополнительную ячейку-заполнитель, повторно используя indexPathForGestureRecognizer
, чтобы получить позицию для нее.
Получайте удовольствие.