Reputation: 303
How to add a new section programmatically to UITableview?
I have pagination and when I try call insertSections in performBatchUpdates it works fine for the first time but when load second page UITableview does't update (no errors just not updated and do not called completion block).
private var periods = [PeriodHistoryModel]()
func fetchHistoryWith(models: [PeriodHistoryModel]) {
guard models.count > 0 else {
return
}
let newSectionsCount = models.count - periods.count
let lastPeriod = periods.count - 1 >= 0 ? periods.count - 1 : 0
var newRows: [IndexPath] = [IndexPath]()
var newSections: [IndexSet] = [IndexSet]()
let lastPeriodOldCount = periods.last?.sessions.count ?? 0
let lastPeriodNewCount = models[lastPeriod].sessions.count
let newSessionsCount = lastPeriodNewCount - lastPeriodOldCount
if lastPeriod >= 0 {>
for index in 0..<newSessionsCount {
newRows.append(IndexPath(row: lastPeriodOldCount + index, section: lastPeriod))
}
}
for index in 0..<newSectionsCount {
let newSectionIndex = periods.count + index
newSections.append(IndexSet(integer: newSectionIndex))
for rowIndex in 0..<models[newSectionIndex].sessions.count {
newRows.append(IndexPath(row: rowIndex, section: newSectionIndex))
}
}
periods = models
tableView.performBatchUpdates({
for index in 0..<newSections.count {
tableView.insertSections(newSections[index], with: .none)
}
tableView.insertRows(at: newRows, with: .none)
})
}
reloadData does not fit need to do it smoothly
Upvotes: 3
Views: 8229
Reputation: 644
The rule of thumb is "update table view models before performing batch updates". I just created a simple project and it works fine. So Make sure your delegate method numberOfSections return the updated model's count.
My project below.
class MyViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
var numberOfSections: Int = 1
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func insertSectionTapped(_ sender: Any) {
numberOfSections += 1
let indexSet = IndexSet(integer: numberOfSections - 1)
tableView.performBatchUpdates({
tableView.insertSections(indexSet, with: .none)
}) { (update) in
print("Update SUccess")
}
}
@IBAction func insertRowTapped(_ sender: Any) {
}
}
extension MyViewController: UITableViewDelegate, UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return numberOfSections
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 2
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell.init(style: .default, reuseIdentifier: "DefaultId")
cell.textLabel?.text = "This is Section \(indexPath.section) - Row \(indexPath.row)"
return cell
}
}
Upvotes: 4