iOS/Swift - UITableView reloadData not being called - ios

I have the following method on my table view controller class:
func reloadInputFields() {
dispatch_async(dispatch_get_main_queue()) {
self.tableView.beginUpdates()
self.tableView.reloadSections(NSIndexSet(index: 1), withRowAnimation: .Automatic)
self.tableView.endUpdates()
}
}
This is called from an NSNotification. The runtime enters this method fine and appears to call reloadSections. However it never actually does. Obviously I am executing on the main thread here as it is a UI update but I have also tried on a background thread. I have also tried just calling tableView.reloadData() instead of reloadSections but no joy there. The table view definitely exists and I have checked that the pointer is correct.
Breakpoints in cellForRowAtIndexPath numberOfSectionsInTableView heightForRowAtIndexPath numberOfRowsInSection etc are not being hit and the table is not reloading.
My delegate and dataSource are set correctly as verified here:
I've been struggling with this for several hours now and it's totally bested me. Any suggestions would be gratefully received.

Some suggestions to solve this issue:
1. Make sure you have IBOutlet connection to the UITableView.
2. Check delegate and datasource. If necessary, write them programmatically.
3. Make sure your tableView is populated with data before triggering notification.
4. Avoid beginUpdates and endUpdates and use only reloadData on main thread.

Is the table view active when the notification is fired?
Check if the table view controller is released (It is not active. Probably not shown on the screen)

Related

Ensembles 2 with NSFetchedResultsControllerDelegate tableView update methods causing crash

Using NSFetchedResultsController delegate method controller
(_:didChange: at:for:newIndexPath:), between tableView.beginUpdates() in controllerWillChangeContent(_:) and tableView.endUpdates() in controllerDidChangeContent(_:), results in objects with nil properties (including the uniqueIdentifier, which is normally set in awakeFromInsert()) being created when merging changes from different devices, and related crash. The problem doesn't occur when only the controllerDidChangeContent(_:) delegate method with tableView.reloadData() is implemented instead.
Any advice on how to eliminate this problem would be appreciated.
Adding tableView.reloadData() in controllerWillChangeContent(_:) just before beginUpdates() seems to solve the problem. It ensures that data in the tableView is in sync with that in the fetchedResultsController (FRC) before the tableView is modified by the FRC delegate methods.

UICollectionView cellForItemAtIndexPath not called after numberOfItemsInSection returns nonzero item number

Is there any reason that cellForItemAtIndexPath would not get called after numberOfItemsInSection gets called and returns a nonzero number? Would a reloadData from a completion block affect this? I'm running into an issue in which I am trying to delete a cell through a UIAlertController and the UI looks great, but when I go to reloadData after the UI animation finishes numberOfItemsInSection properly gets called with the right number of elements (the previous number of elements minus 1), yet cellForItemAtIndexPath does not get called, so my cells don't get reloaded. Any ideas as to why this would happen?
This is on Swift 1.2, XCode 6.4, and any help would be greatly appreciated
Just to give a bit more information, the method I'm using to delete a cell is looking a little like:
self.collectionView.performBatchUpdates({
let indexPathCellToDelete = self.indexPath(feedCell)
self.collectionView.deleteItemsAtIndexPaths([indexPathCellToDelete])
}, completion:nil)
Would having a second reload in the completion block change anything?
Turns out performBatchUpdates, according to UICollectionView Performing Updates using performBatchUpdates needs to be called after the change to my data source has been done. The issue was, though, that my method for deleting an item from my data source itself reloads the collection view, so there was an extra reload that did not need to happen, which was causing the issue, it seems. I initially had the call to my data source deletion method in the completion block of the performBatchUpdates, but moving that above and just reloading the entire collection view seems to have solved the issue. Seems like a weird race condition in my case where there are multiple reloads happening simultaneously and cellForItemAtIndexPath didn't like that.

Using reloadRowsAtIndexPaths when the update of a NSFetchedResultsController is triggered

I have some rows of my UITableView that get updated and then trigger the method controller:didChangeObject:atIndexPath:forChangeType:newIndexPath of the NSFetchedResultsControllerDelegate delegate.
I usually update the rows in the tableView using reloadRowsAtIndexPaths with an animation, but it happens that sometimes the method is triggered because of a change that is not visible and is that case, I don't want to reload the row with an animation.
The method doesn't give the previous state of the object. Is there a way to do it (I didn't find any method of the delegate that might do)?
If your delegate is also your TableViewController, you could just check your UITableView's data source at the IndexPath. The reloadRowsAtIndexPaths method knows the index.

numberOfRowsInSection returns more than 0; cellForRowAtIndexPath still not being called

I notice this problem is very common and there are alot of posts about it but none of the solutions i tried so far worked.
So I have a delegate method that updates the datasource: NSArray * posts and reload the table view. I am positive that posts is updated before the reload call because i logged it.
It calls the numberOfRowInSection method and [posts count] returns more than 0 every time. but the cellForRowAtIndexPath is still not called.
the tableview is created from the IB and content is currently shows content and the cells before the reload. i need one of the cells content to be updated but it doesnt because cellForRowAtIndexPath is not called.
This only happens for the delegate method.
I tried making the reload call on the main thread using both gcd and perform selectorOnMainThread still no go.
Any ideas what maybe causing this problem and how to fix it?
Make sure you have UITableViewDataSource, UITableViewDelegate in your .h and connected the tableview delegate, data source and cellindentifier Cell in .xib.
have you registered your cell ?
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"Cell"];
Load your tableView in method
awakeFromNib
this solved my problem.

UITableView reloadData and cellForRowAtIndexPath - interruptable?

Let's assume there exists a UITableView called myTable. Let's say the following sequence of events occur --
Table is fully populated.
The data source is updated (in this case an sqlite3 db, but doesn't really matter), an NSNotifcation happens to indicate that there is new data, the main thread receives the notification and then calls [myTable reloadData].
myTable's UITableViewDataSource's numberOfSectionsInTableView gets called. Assume only 1 section.
myTable's UITableViewDataSource's tableView:numberOfRowsInSection: gets called.
Several tableView:cellForRowAtIndexPath:'s get called depending on the number of rows in the data source.
My question has to do with the interruptability of cellForRowAtIndexPath.
The question --
If a "reloadData" is called and cellForRowAtIndexPath's are getting called AND another reloadData comes in, will the cellForRowAtIndexPath's stop midstream and restart after the calls to numberOfSectionsInTableView and numberofRowsInSection?
Or will the new reloadData be queued, such that all of the cellForRowAtIndexPaths will finish BEFORE the numberOfSectionsInTableView and numberOfRowsInSection get called?
I've looked and have been unsuccessful in finding an answer to this question in docs or the net. I'm concerned that if the data store is updated while the cellForRowAtIndexPaths are "running", the numberOfSectionsInTableView can change which can result in the cellForRowAtIndexPath requesting data for a cell that's now out of range.
Any help would be greatly appreciated.
Since you should only call reloadData on the main thread and since by the time a call to reloadData is done, all of the visible cells have already been loaded, there is no problem to worry about. The second call to reloadData will be made after the 1st one is done.
I don't think it is possible to be in the middle of cellForRowAtIndexPath when reloadData is called assuming they are both called on the same (main) thread (having an async processing on background thread at cellForRowAtIndexPath seems meaningless).

Resources