Ich implementiere reduzierbare Abschnittsüberschriften in einem UITableViewController.
So bestimme ich, wie viele Zeilen pro Abschnitt angezeigt werden sollen:
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return self.sections[section].isCollapsed ? 0 : self.sections[section].items.count
}
Es gibt eine Struktur, die die Abschnittsinformationen mit einem Bool für 'isCollapsed' enthält.
So schalte ich ihre Zustände um:
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()
}
Alles funktioniert und animiert gut, aber in der Konsole beim Ausblenden eines erweiterten Abschnitts erhalte ich Folgendes: [Assert]:
[Assert] Neuer globaler Zeilenindex für preReloadFirstVisibleRow (0) kann nicht ermittelt werden
Dies geschieht unabhängig davon, ob es sich um denselben geöffneten Abschnitt handelt, der geschlossen (reduziert) wird oder ob ich einen anderen Abschnitt öffne und den zuvor geöffneten Abschnitt automatisch schließe.
Ich mache nichts mit den Daten; das ist hartnäckig.
Könnte jemand helfen zu erklären, was fehlt? Vielen Dank
quelle
Antworten:
Damit eine tableView weiß, wo sie sich befindet, während sie Zeilen usw. neu lädt, versucht sie, eine "Ankerzeile" zu finden, die sie als Referenz verwendet. Dies nennt man a
preReloadFirstVisibleRow
. Da diese tableView möglicherweise irgendwann keine sichtbaren Zeilen mehr hat, weil alle Abschnitte reduziert sind, wird die tableView verwirrt, da sie keinen Anker finden kann. Es wird dann nach oben zurückgesetzt.Lösung: Fügen Sie jeder Gruppe, die reduziert ist, eine Zeile mit der Höhe 0 hinzu. Auf diese Weise ist auch dann noch eine Zeile vorhanden, wenn ein Abschnitt reduziert ist (wenn auch mit einer Höhe von 0 Pixel). Die tableView hat dann immer etwas als Referenz. Sie sehen dies, indem Sie eine Zeile in
numberOfRowsInSection
hinzufügen, wenn die Zeilenanzahl 0 ist, und weitereindexPath.row
Aufrufe bearbeiten, indem Sie sicherstellen, dass der Phatom-Zellenwert zurückgegeben wird, bevor erindexPath.row
benötigt wird, wenn diedatasource.visibleRows
0 ist.Es ist einfacher, im Code zu demonstrieren:
quelle