UITableView Прокрутка вверх после вставки строки - PullRequest
0 голосов
/ 12 октября 2018

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

Моя проблема в том, что мне нужно прокрутить до расширенного раздела, а также избавиться от ошибки прокрутки до верха.

Я пробовал приведенное ниже решение, но у меня не получилось: предотвратить таблицувид сверху прокрутки после insertRows

Это также похоже на ту же проблему с вопросом ниже, но не может понять, как это реализовать. Почему мой UITableView «прыгает» при вставке или удалении строки?

Как переключать выбор:

func toggleSection(header: DistrictTableViewHeader, section: Int) {
    print("Trying to expand and close section...")
    // Close the section first by deleting the rows
    var indexPaths = [IndexPath]()
    for row in self.cities[section].districts.indices {
        print(0, row)
        let indexPath = IndexPath(row: row, section: section)
        indexPaths.append(indexPath)
    }

    let isExpanded = self.cities[section].isExpanded
    if(isExpanded){
        AnalyticsManager.instance.logPageEvent(screenName: analyticsName!, category: "Button", action: Actions.interaction, label: "\(self.cities[section].name) Collapse Click")
    }else{
        AnalyticsManager.instance.logPageEvent(screenName: analyticsName!, category: "Button", action: Actions.interaction, label: "\(self.cities[section].name) Expand Click")
    }
    self.cities[section].isExpanded = !isExpanded

    // This call opens CATransaction context
    CATransaction.begin()
    // This call begins tableView updates (not really needed if you only make one insertion call, or one deletion call, but in this example we do both)
    tableView.beginUpdates()
    if isExpanded {

        tableView.deleteRows(at: indexPaths, with: .automatic)
    } else {
        tableView.insertRows(at: indexPaths, with: .automatic)
    }
    // completionBlock will be called after rows insertion/deletion animation is done
    CATransaction.setCompletionBlock({
        // This call will scroll tableView to the top of the 'section' ('section' should have value of the folded/unfolded section's index)
            if !isExpanded{
                self.tableView.scrollToRow(at: IndexPath(row: NSNotFound, section: section) /* you can pass NSNotFound to scroll to the top of the section even if that section has 0 rows */, at: .top, animated: true)
            }
    })

    if self.scrollToTop(){
        self.tableView.setContentOffset(.zero, animated: true)
    }
    // End table view updates
    tableView.endUpdates()


    // Close CATransaction context
    CATransaction.commit()

}

private func scrollToTop() -> Bool{
    for sec in self.cities{
        if(sec.isExpanded){
            return false
        }
    }
    return true
}

Iдаю высоту ячейки внутри;

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 120
}

Как я объявляю заголовки;

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {

    let header = DistrictTableViewHeader()
    header.isColapsed = !self.cities[section].isExpanded
    header.customInit(title: self.cities[section].name, section: section, delegate: self)
    return header
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return 60
}

РЕДАКТИРОВАТЬ: Решение вэтот вопрос (установка приблизительной высоты в 0) выглядит как работающий при вставке строки.Тем не менее, у меня все еще есть ошибка при удалении строк.Нижний заголовок переходит в центр табличного представления, а затем - после заголовка свертывания.

iOS 11 Плавающий заголовок TableView

Ответы [ 4 ]

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

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

Надеюсь, это поможет вам, спасибо

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

Вы можете попробовать использовать приведенный ниже код.Просто получите последнее смещение контента вашего просмотра таблицы.Затем выполните обновление и переназначьте смещение содержимого.

let lastOffset = tableView.contentOffset
self.tableView.beginUpdates()
self.tableView.layer.removeAllAnimations()
self.tableView.endUpdates()
tableView.contentOffset = lastOffset
0 голосов
/ 26 октября 2018

Простое решение swift3 и выше

используйте расширение ниже как

например: tableViewOutlet.tableViewScrollToBottom (animated: true)

extension UITableView {

    func tableViewScrollToBottom(animated: Bool) {

        DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(100)) {

            let numberOfSections = self.numberOfSections
            let numberOfRows = self.numberOfRows(inSection: numberOfSections-1)
            if numberOfRows > 0 {
                let indexPath = IndexPath(row: 0, section: 0)
                self.scrollToRow(at: indexPath, at: UITableView.ScrollPosition.top, animated: animated)
            }
        }
    }
}
0 голосов
/ 22 октября 2018

Вместо tableView.beginUpdates() и tableView.endUpdates(). В моем коде я использую tableView.reloadData() для расширения и сжатия конкретного раздела. Вы можете вызывать reloadData, когда вам необходимо обеспечить расширение раздела.Это приводит к тому, что у вас нет проблемы с прокруткой анимации вверх.И отлично работает в моем проекте, где я должен показать количество строк в определенном разделе одним нажатием кнопки, которая включает в себя этот раздел.

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if section == 0 {
        return 1
    }
// Ignore the If Else statements it's just when do you need expansion of section.
    else {
        if showMore == true {
            return self.userPoints.rewardsData[section - 1].count - 1
        }
        else {
            return 0
        }
    }
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...