Изменение порядка разделов в UITableView - PullRequest
0 голосов
/ 02 октября 2018

У меня есть UITableView с разделами и строками (https://imgur.com/a/hrYTEVR). Я знаю, как включить переупорядочение для строк, но я не знаю, как реализовать переупорядочение для разделов. Мне нужно добавить элемент управления переупорядочением для разделов (https://imgur.com/a/V5kU9Ew) изатем, когда пользователь прикоснется к этому элементу управления, строки в разделе должны перебраться. После этого пользователь сможет переместить раздел на новое место. После прочтения тем на stackoverflow и других сайтах я не найду никакой хорошей идеи, как реализовать что-то подобное. Я думал о реализации разделов черезячеек, но в этом случае я не могу переключать строки в разделе для дальнейшего перемещения на новое место. Если у вас есть идеи, как это реализовать - дайте мне совет. Спасибо!

Ответы [ 2 ]

0 голосов
/ 02 октября 2018

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

Жест должен быть относительно очевидным.После того, как он начинается в заголовке, вам нужно отслеживать позицию, используя 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, чтобы получить позицию для нее.

Получайте удовольствие.

0 голосов
/ 02 октября 2018

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

func numberOfSections(in tableView: UITableView) -> Int{ 
    return yourSectionNumber 
}

Затем для каждого раздела вам нужно указать:

func headerView(forSection section: Int) -> UITableViewHeaderFooterView? {
    return yourSpecifiedHeaderView
}

Или, если вы хотите представление заголовка по умолчаниюдля раздела, который предоставляет Apple, вы можете использовать:

func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
     return yourSectionTitle
}

Затем для заказа вы можете заказать свои разделы вместе с данными вместе.Здесь предлагается создать собственный класс, который будет содержать данные строки tableView.Например:

class Foo {
    var sectionTitle: String
    var data: [AnotherClassForData]
}

class AnotherClassForData {
    var rowTitle: String
   // other properties
}

Тогда в вашем tableView у вас будет массив объектов вашего класса Foo.Например:

var dataSource = [Foo]()

func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
     return dataSource[section].sectionTitle
}

Затем где-то в коде вы можете изменить его порядок следующим образом:

dataSource.sorted(by: { $0.sectionTitle > $1.sectionTitle } ) 

Затем вы можете перезагрузить свой tableView как всегда:

DispatchQueue.main.async {
    self.tableView.reloadData()
}
...