Странное поведение прокрутки UITableView с большим заголовком панели навигации, эффектом отскока вверху, автоматическое отключение / отрывистый при прокрутке вверх

#ios #swift #uitableview

#iOS #swift #uitableview

Вопрос:

У меня есть UITableView с несколькими разделами с заголовком, сворачиваемым / расширяемым. А также tableHeaderView с пользовательским UIView .

Используя пользовательский заголовок раздела UIView , а также пользовательский UITableViewCell .

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

Удивительно, но когда я свернул все строки первого раздела, поведение прокрутки вернулось к нормальному.

Вот gif, показывающий запись моего экрана.

https://i.imgur.com/WwXmpmZ.gifv

Я установил следующее для своего UITableView :

 self.tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 15, right: 0)
self.tableView.estimatedRowHeight = 0 
self.tableView.estimatedSectionHeaderHeight = 0
self.tableView.estimatedSectionFooterHeight = 0
  

Я также пробовал:

 self.tableView.contentInsetAdjustmentBehavior = .never
  

Это действительно решило проблему странного поведения прокрутки, однако это приводит к тому, что заголовки моих разделов и строки перекрываются с моим tableHeaderView.

То, как я обрабатываю сворачивание / разворачивание. Если свойство object isCollapsed равно true, я просто возвращаю строку 0 для этого раздела:

 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    if section == self.scheduleCount {
        //Last section
        return self.dataSource.count
    }

    guard let schedule = self.itineraryDataSource?.schedule[section] else { return 0 }

    if schedule.isCollapsed {
        return 0
    } else {
        return schedule.items.count
    }
}
  

Это все делегаты высоты, последний раздел отличается UITableViewCell , отсюда и разная высота.

 func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {

    if section == self.scheduleCount {
        //Last section
        return 40
    }

    return 64
}

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    if indexPath.section == self.scheduleCount {
        //Last section
        return 112
    } else {
        return 76
    }
}
  

Комментарии:

1. Как вы вставляете новые строки табличного представления? Загрузите код для того же.

2. @SachinVas Я отредактировал свой пост, чтобы включить больше кода о том, как я управляю свертыванием / расширением, а также делегатами высоты. Я делаю это всякий раз, когда нажимается заголовок раздела, чтобы свернуть / развернуть: self.tableView.reloadSections([section], with: .fade)

Ответ №1:

Удалось это исправить.

Оказывается, я возвращался UIView за своим viewForHeaderInSection , и я не использовал tableView.dequeueReusableHeaderFooterView . Я буквально инициализирую новый xib UIView каждый раз, когда прокручиваю tableView , что заставляет его автоматически корректировать вставку содержимого, следовательно, вызывает отрывистую прокрутку.

Итак, я создал новый пользовательский xib для моего вида заголовка раздела с типом UITableViewHeaderFooterView и просто вернул его в viewForHeaderInSection .

 func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let dayHeaderView = tableView.dequeueReusableHeaderFooterView(withIdentifier: "ItineraryDayHeaderView") as? ItineraryDayHeaderView

    // Configure View...

    return dayHeaderView
}