4

I need to reload the section excluding the header after I do some sort on my tableview data. That's to say I just want to reload all the rows in the section. But I don't find a easy way to make it after I search for a while.

reloadSections(sectionIndex, with: .none) not works here, for it will reload the whole section including the header, footer and all the rows.

So I need to use reloadRows(at: [IndexPath], with: UITableViewRowAnimation) instead. But how to get the whole indexPaths for the all the rows in the section.

LF00
  • 27,015
  • 29
  • 156
  • 295
  • 1
    you know how many rows have one section with the datasource method of the table numberOfRowForSection(yourSection) then you need to create an array of indexPaths with section = yoursectionNumber and row from 0.. – Reinier Melian May 16 '18 at 09:45

5 Answers5

11

You can use below function get IndexPath array in a given section.

func getAllIndexPathsInSection(section : Int) -> [IndexPath] {
    let count = tblList.numberOfRows(inSection: section);        
    return (0..<count).map { IndexPath(row: $0, section: section) }
}

Or

func getAllIndexPathsInSection(section : Int) -> [IndexPath] {
    return tblList.visibleCells.map({tblList.indexPath(for: $0)}).filter({($0?.section)! == section}) as! [IndexPath]
}
PPL
  • 6,357
  • 1
  • 11
  • 30
7

In my opinion, you don't need reload whole cells in the section. Simply, reload cells which is visible and inside section you need to reload. Reload invisible cells is useless because they will be fixed when tableView(_:cellForRowAt:) is called.

Try my below code

var indexPathsNeedToReload = [IndexPath]()

for cell in tableView.visibleCells {
  let indexPath: IndexPath = tableView.indexPath(for: cell)!

  if indexPath.section == SECTION_INDEX_NEED_TO_RELOAD {
    indexPathsNeedToReload.append(indexPath)
  }
}

tableView.reloadRows(at: indexPathsNeedToReload, with: .none)
trungduc
  • 11,926
  • 4
  • 31
  • 55
  • @vacawama Actually I want to use it but I'm not good enough at Swift to do it. I think I got it with Ashley Mills's help – trungduc May 16 '18 at 09:56
  • 1
    For someone who gives downvote. Please leave a comment for reason. – trungduc May 16 '18 at 10:00
  • Why're you posting someone else answer by mentioning his name when he himself posted the answer. Although I'm not downvoter. – TheTiger May 16 '18 at 10:03
  • @TheTiger You should know that I'm the first one give this answer (You can check it by answered time). After that he leaves a comment on my answer with these code. I just update it with his help. But don't know why he removed it and add his answer which has his code and my answer content. So what do you think about it? – trungduc May 16 '18 at 10:05
  • 2
    Yes I saw! But what can do. Might be he thought he can earn some repo. But I agreed the original idea about visible cells is yours. So +1 for that only. – TheTiger May 16 '18 at 10:07
  • @TheTiger Even I don't know he added his answer when I update my answer. Should my answer receive a downvote in this situation? Any way, I removed his code from my answer. Please reconsider your decision – trungduc May 16 '18 at 10:12
  • 1
    I have already said I didn't down vote and why would I? Even I voted up for using `tableView.visibleCells`. – TheTiger May 16 '18 at 10:13
  • Sorry, I got it. Thanks! – trungduc May 16 '18 at 10:15
7

You can get the indexPaths for reloading like this…

let indexPaths = tableView.visibleCells
    .compactMap(tableView.indexPath)
    .filter { $0.section == SECTION }

There's no need to reload non-visible cells, as they will be updated when cellForRow(at indexPath:) is called

Ashley Mills
  • 50,474
  • 16
  • 129
  • 160
1

Iterate over the index paths in a section using the numberOfRows inSection method of UITableView. Then you can build your IndexPath array:

var reloadPaths = [IndexPath]()
(0..<tableView.numberOfRows(inSection: sectionIndex)).indices.forEach { rowIndex in
    let indexPath = IndexPath(row: rowIndex, section: sectionIndex)
    reloadPaths.append(indexPath)
}
tableView.reloadRows(at: reloadPaths, with: UITableViewRowAnimation)
davidethell
  • 11,708
  • 6
  • 43
  • 63
-1

You can get all the visible index paths directly, and then filter them however you want, i.e.

func reloadRowsIn(section: Int, with animation: UITableView.RowAnimation) {
    if let indexPathsToReload = indexPathsForVisibleRows?.filter({ $0.section == section }) {
        reloadRows(at: indexPathsToReload, with: animation)
    }
}