Я реализую сворачиваемые заголовки разделов в UITableViewController.
Вот как я определяю, сколько строк показывать на раздел:
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return self.sections[section].isCollapsed ? 0 : self.sections[section].items.count
}
Существует структура, которая содержит информацию о разделе с помощью bool для isCollapsed.
Вот как я переключаю их состояния:
private func getSectionsNeedReload(_ section: Int) -> [Int]
{
var sectionsToReload: [Int] = [section]
let toggleSelectedSection = !sections[section].isCollapsed
// Toggle collapse
self.sections[section].isCollapsed = toggleSelectedSection
if self.previouslyOpenSection != -1 && section != self.previouslyOpenSection
{
self.sections[self.previouslyOpenSection].isCollapsed = !self.sections[self.previouslyOpenSection].isCollapsed
sectionsToReload.append(self.previouslyOpenSection)
self.previouslyOpenSection = section
}
else if section == self.previouslyOpenSection
{
self.previouslyOpenSection = -1
}
else
{
self.previouslyOpenSection = section
}
return sectionsToReload
}
internal func toggleSection(_ header: CollapsibleTableViewHeader, section: Int)
{
let sectionsNeedReload = getSectionsNeedReload(section)
self.tableView.beginUpdates()
self.tableView.reloadSections(IndexSet(sectionsNeedReload), with: .automatic)
self.tableView.endUpdates()
}
Все хорошо работает и анимируется, однако в консоли при свертывании расширенного раздела я получаю [Assert]:
[Assert] Невозможно определить новый глобальный индекс строки для preReloadFirstVisibleRow (0)
Это происходит независимо от того, является ли это тем же открытым разделом, закрывается (сворачивается) или я открываю другой раздел и автоматически закрываю ранее открытый раздел.
Я ничего не делаю с данными; это постоянно.
Может ли кто-нибудь помочь объяснить, чего не хватает? Спасибо
ios
swift
assert
collapsable
uitableviewsectionheader
iOSProgrammingIsFun
источник
источник
Ответы:
Чтобы tableView узнал, где он находится, пока он перезагружает строки и т. Д., Он пытается найти «якорную строку», которую он использует в качестве ссылки. Это называется
preReloadFirstVisibleRow
. Так как этот tableView может не иметь видимых строк в какой-то момент из-за того, что все разделы свернуты, tableView будет сбит с толку, так как не может найти привязку. Затем он будет сброшен на вершину.Решение: добавьте строку высоты 0 к каждой свернутой группе. Таким образом, даже если секция свернута, все еще присутствует строка (хотя и с высотой 0px). В этом случае tableView всегда есть что-то, на что можно ссылаться. Вы увидите это в действительности, добавив строку в,
numberOfRowsInSection
если rowcount равен 0, и обработав любые дальнейшиеindexPath.row
вызовы, убедившись, что необходимо вернуть значение ячейки phatom прежде,indexPath.row
если значениеdatasource.visibleRows
равно 0.Демо проще в коде:
источник