В случае, если кому-то интересна версия приведенного выше кода на Swift 4.2, вот она.
Чтобы иметь вложенные разделы, вам нужно иметь несколько видов строк в вашем tableView.Первый представляет второй уровень секций, а второй представляет стандартные строки в вашем tableView.Допустим, у вас есть двухуровневый массив (разделы) для представления элементов в вашем tableView.
Тогда общее количество разделов, которое у нас есть, это просто количество разделов верхнего уровня.Число строк в каждом разделе верхнего уровня будет равно числу подразделов + количество строк в каждом подразделе.
func numberOfSections(in tableView: UITableView) -> Int {
return sections.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let sectionItems = sections[section]
var numberOfRows: Int = sectionItems.count // For second level section headers
for rowItems: [Any] in sectionItems as? [[Any]] ?? [] {
numberOfRows += rowItems.count // For actual table rows
}
return numberOfRows
}
Теперь все, что вам нужно подумать, - это как создать строки дляTableview.Установите два прототипа в раскадровке с разными идентификаторами повторного использования, один для заголовка раздела и другой для элемента строки, и просто создайте правильный экземпляр на основе запрашиваемого индекса в методе источника данных.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var sectionItems = sections[indexPath.section]
var sectionHeaders = self.sectionHeaders[indexPath.section]
let itemAndSubsectionIndex: IndexPath? = computeItemAndSubsectionIndex(for: indexPath)
let subsectionIndex = Int(itemAndSubsectionIndex?.section ?? 0)
let itemIndex: Int? = itemAndSubsectionIndex?.row
if (itemIndex ?? 0) < 0 {
// Section header
let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "SECTION_HEADER_CELL", for: indexPath)
cell.textLabel?.text = sectionHeaders[subsectionIndex] as? String
return cell
} else {
// Row Item
let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "ROW_CONTENT_CELL", for: indexPath)
cell.textLabel?.text = sectionItems[subsectionIndex][itemIndex ?? 0] as? String
return cell
}
}
func computeItemAndSubsectionIndex(for indexPath: IndexPath?) -> IndexPath? {
var sectionItems = sections[Int(indexPath?.section ?? 0)]
var itemIndex: Int? = indexPath?.row
var subsectionIndex: Int = 0
for i in 0..<sectionItems.count {
// First row for each section item is header
itemIndex = (itemIndex ?? 0) - 1
// Check if the item index is within this subsection's items
let subsectionItems = sectionItems[i] as? [Any]
if (itemIndex ?? 0) < Int(subsectionItems?.count ?? 0) {
subsectionIndex = i
break
} else {
itemIndex -= subsectionItems?.count
}
}
return IndexPath(row: itemIndex ?? 0, section: subsectionIndex)
}