简体   繁体   中英

Reload tableView section without reloading header section - Swift

I'm trying to reload tableView section instead of reloading the whole tableview because I have a textfield in the header section and when I call self.tableView.reloadData() my keyboard get closed.

I've tried the code below but I get this error Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to delete row 5 from section 2 which only contains 4 rows before the update' So please where would be my issue?

    let newCount = self.placeArray.count

    var newIndexPaths = NSMutableArray(capacity: newCount)

    for var i = 0 ; i < newCount ; i++ {
    var indexPath = NSIndexPath(forRow: i, inSection: 2)
        newIndexPaths.addObject(indexPath)
    }

    self.tableView.beginUpdates()
    self.tableView.reloadRowsAtIndexPaths(newIndexPaths as [AnyObject], withRowAnimation: UITableViewRowAnimation.None)
    self.tableView.endUpdates()

您可以改用UITableViewreloadSections方法。

tableView.reloadSections(IndexSet(integer: 2), with: .none)

Swift 3.0.1:

let sectionIndex = IndexSet(integer: 0)

tableView.reloadSections(sectionIndex, with: .none) // or fade, right, left, top, bottom, none, middle, automatic

Swift 3.1 Xcode 8.3.3 Answer :)

The problem is - each section includes header of course, so section is:

section = header + footer + rows

The answer is - reload rows directly by IndexPath. Example:

  1. Let's say you've got 1 section in your table and 'array' of something you use as datasource for table:

    let indexes = (0..<array.count).map { IndexPath(row: $0, section: 0) }

  2. Now we've got array of indexes of cell we want to reload, so:

    tableView.reloadRows(at: indexes, with: .fade)

Note:

  • UITableView.reloadData() will reload all the table. Docs about reloaddata

    reload all the data that is used to construct the table, including cells, section headers and footers, index arrays, and so on. For efficiency, the table view redisplays only those rows that are visible. It adjusts offsets if the table shrinks as a result of the reload. The table view's delegate or data source calls this method when it wants the table view to completely reload its data.

  • UITableView.reloadSections(_ sections: IndexSet, with animation: UITableViewRowAnimation) will reload specific section( including section header and section footer ). Docs about reloadsections

  • UITableView.reloadRows(at indexPaths: [IndexPath], with animation: UITableViewRowAnimation) will reload the specified rows. Docs about reloadRows

So here reloadSections will not works here. If your header section data and status not change, call this method will make no diffrence by sight.

Solution: use reloadRows to load the rows of all the sections or of the specific section. Note: here you can just load the visible rows, others will be loaded when you scroll you view. You also can refer to Get all indexPaths in a section for more solutions

var indexPaths = self.tableView.indexPathsForVisibleRows

/* just roload visible rows of specified section
indexPaths = indexPaths.filter({ (indexPath) -> Bool in
    return indexPath.section == SECTION_INDEX_NEED_TO_RELOAD
})
*/
self.tableView.reloadRows(at: indexPaths!, with: .none)

Swift 5

You can just reload section as below:

tableView.reloadSections([0], with: .none)

or

tableView.reloadSections(IndexSet(integer: 0), with: .none)

Here zero represent the index it will reload.

Reload multiple sections:

tableView.reloadSections([0, 1, 3], with: .none)

Swift 5

Here is put static index reload which is 1st index, you can change as per your requirement.

self.tblView.reloadSections(IndexSet(index: 1), with: .none)

[Swift 5]

You want to reload all rows in a section. So you can do:

let rowIndexes: [IndexPath] = Array(0...YOUR_ARRAY-1).map({ 
    return IndexPath(row: $0, section: YOUR_SECTION) 
})

To get all possible row indexes for this section. Then you just have to reload rows for these indexes:

tableView.reloadRows(at: rowsIndexes, with: .fade)

The section won't be reloaded.

I might be late to the party but here is a solution for 2D array (in case if your tableView has sections and each section has some items). This will reload every cell in every section but won't touch header/footer of the section.

    let indexPaths = (0..<array.count).map { section in
        (0..<array[section].nestedArray.count).map { IndexPath(row: $0, section: section) }
    }.flatMap { $0 }
    tableView.reloadRows(at: indexPaths, with: .fade)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM