17

Is there a way to reload specific UITableView cells with multiple sections with animations?

I've been using:

self.TheTableView.reloadSections(NSIndexSet(index: 1), withRowAnimation: UITableViewRowAnimation.Right)

This animates all the cells in the section though. The other option is to use:

self.TheTableView.reloadRowsAtIndexPaths(<#indexPaths: [AnyObject]#>, 
                                         withRowAnimation: <#UITableViewRowAnimation#>)

EDIT:

After using reloadRowsAtIndexPaths

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 1. The number of rows contained in an existing section after the update (5) must be equal to the number of rows contained in that section before the update (4), plus or minus the number of rows inserted or deleted from that section (0 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'

Trying to find a smooth way of reloading a tableview by appending objects into an array.

Calling TheTableView.reloadData() before reloadRowsAtIndexPaths works, but the animation is glitchy. Is there another approach?

William Larson
  • 593
  • 3
  • 8
  • 16

4 Answers4

13

Why not just reload the cells directly? The indexPath contains the section and row so just keep track of which section you want to reload and fill the indexes in that array.

var indexPath1 = NSIndexPath(forRow: 1, inSection: 1)
var indexPath2 = NSIndexPath(forRow: 1, inSection: 2)
self.tableView.reloadRowsAtIndexPaths([indexPath1, indexPath2], withRowAnimation: UITableViewRowAnimation.Automatic)

Based on your comment you are looking to change your array and have the tableView animate in the changes. If that's the case you should consider using beginUpdates() and endUpdates() for UITableViews or even an NSFetchedResultsController so it handles all of the update animations cleanly.

self.tableView.beginUpdates()
// Insert or delete rows
self.tableView.endUpdates()

I'd recommend using NSFetchedResultsController if you're using Core Data as it simplifies this entire process. Otherwise you have to handle the changes yourself. In other words, if your array changes you need to manually remove or insert rows in the tableview using beginUpdates() and endUpdates(). If you aren't using Core Data, study this to grasp how it's all handled.

Mark McCorkle
  • 9,349
  • 2
  • 32
  • 42
  • Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 1. The number of rows contained in an existing section after the update (5) must be equal to the number of rows contained in that section before the update (4), plus or minus the number of rows inserted or deleted from that section (0 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).' – William Larson Apr 14 '15 at 16:34
  • This could work, but I need to reload the data before I can call reloadRowsAtIndexPaths. I'm going to fiddle with this a little bit. Maybe calling ReloadData just before that command? – William Larson Apr 14 '15 at 16:36
  • You can't call reloadData if you're wanting a clean animation. Look into beginUpdates() and endUpdates() if your data is changing. UITableViewControllers utilize this to make things much easier (if it fits your app model) – Mark McCorkle Apr 14 '15 at 16:36
  • So I tried your solution, but It does not seem to fix the crashing, no matter where I place beginUpdates() and endUpdates(). I basically have an IBAction which appends data into an array. which also needs to reload the tableView and animate just the specific added cell. – William Larson Apr 14 '15 at 16:59
  • At the time `endUpdates` is called (or when you call the `reloadRow`, `insertRowsAtIndexPaths`, `deleteRowsAtIndexPaths` without calling beginUpdates the delegate must be set to return the correct row counts and cells on request. – Joseph Lord Apr 14 '15 at 23:31
5

In Swift 3.0

We can reload particular row of particular section in tableview

let indexPath = IndexPath(item: 2, section: 0)
self.tableView.reloadRows(at: [indexPath], with: .automatic)
jaiswal Rajan
  • 4,641
  • 1
  • 27
  • 16
3

If you want to reload single section in swift 3.0 you can do this:

tableView.reloadSections(IndexSet(integer: 0), with: .automatic)
alessioarsuffi
  • 561
  • 5
  • 16
3

the define IndexSet in official document:

Manages a Set of integer values, which are commonly used as an index type in Cocoa API. The range of valid integer values is in (0, INT_MAX-1). Anything outside this range is an error.

so IndexSet is Set about index, just putting some Int values in [ ]

// for reload one section
tableView.reloadSections([section], with: .automatic)
// or using like this
tableView.reloadSections(IndexSet(integer: section), with: .automatic)

// for reload multi sections
tableView.reloadSections([1, 2, 3, section], with: .automatic)
Junhang Lv
  • 31
  • 3
  • 1
    Please add more description and/or information about your answer and how it solves the asked problem so others can easily understand it without asking for clarification – koceeng Mar 04 '17 at 02:53
  • Hi @koceeng , I'm new in Swift. as far as I know, IndexSet is a set about index, and official document explain it when define IndexSet: /// Manages a `Set` of integer values, which are commonly used as an index type in Cocoa API. /// The range of valid integer values is 0.. – Junhang Lv Mar 04 '17 at 07:30
  • Don't get me wrong. Your answer is more than welcome here, we really appreciate it. But it will be more interesting and easier to understand if you provide some detail/description. Actually, your comment above is really good to be mentioned inside your answer, you see. Because a lot of times, one who seek for answer just ignore the comment. You can edit your answer and include your comment above. Good day :) – koceeng Mar 04 '17 at 09:51
  • 1
    Hi @koceeng, In fact, I'm anxious about my poor English. Thanks for your advise, I had reedit it. – Junhang Lv Mar 06 '17 at 11:01