I have a UITableView and I charged it with data in viewDidAppear. and it run successfully.
The Problem is I should refresh the data of the UITableView frequently (every 300 seconds).
So I defined a timer and charged the UITableView's dataSource when the timer throws the event of finishing time interval (300 secs).
BUT Nothing change !!!
The data stills as it was.
Any help would be appreciated.
Sorry for my english.
Try [tableView reloadData]
You don't fill the data actively, you just implement the data source delegates.
If the data has changed, use [yourTableView reloadData] to refresh, the table will fetch the data it needs. There are methods for reloading sections or a couple of rows, too, if you know what changed and want to animate this.
Also, make sure to call on the main thread (in case your timer fires on another thread).
Related
I have read several articles about UITableView, including the official doc and some on SO. But my situation seems to be different.
I want to update the Table each time the view loaded. And I must fetch the data using HTTP request.
What I got now is:
When enter the table view, I should use a non-synchronous HTTP request to update the data. Because I don't want the main thread to wait. One place to do that, is in the tableView:cellForRowAtIndexPath: method. So I return 0 for no data exist at the beginning.
When I get the HTTP respond, I update rows on main thread using beginUpdates endUpdates insertRowsAtIndexPaths:withRowAnimation:
And I must update the "Data Source" at the same time, but how to do that?
Or should I make a daemon thread and update my data every once in a while? So that the data will be ready when TableView is loaded.
You would do it like this:
Have a boolean or some variable where you can reliably detect whether you have all the data.
In viewWillAppear, reset everything. Start loading your data.
If you don't have the data yet, you only display one section with one cell (a placeholder cell that reads "Loading..." and shows a spinner, for instance).
Once the data is completely loaded, you set the bool or whatever.
Call [self.tableView reloadData];
In all of your UITableViewDataSource methods you would need to check whether you've got the data already or not. If not, you return the placeholder data.
[yourtablename reloadData]; will help you relaod the data in the tableview, You can call this once you get the response from your server
I'm not sure there's a "best method" for what you're trying to accomplish here. I would suggest trying the method you have, and seeing if it provides an adequate user experience (whatever that means to you) and if it doesn't, try something else. I would definitely suggest having some sort of "loading" indicator while the table is empty and waiting for http response.
In terms of your question about the "data source", the data source of a UITableView is simply an object that implements the UITableViewDataSource protocol which you can read about here. Often times, you will have XCode set up a UITableViewController object which will act as both delegate and data source to your table view. How you actually store your data is up to you. The data source protocol simply provides the methods by which a table view will "ask" for the data it needs to load.
I am updating my table data resource and then I am calling
[self.tableView reloadData]
to load the table view with this new data. This is all happening in a thread. Now, it works fine with lets say I add 4-5 objects but at some point it stops calling the cellForRowAtIndexPath to reload the table with new data.
Data source is getting updated all the time to contain latest data. So, data source has 10 objects but I can see only 5 on the screen. And it keeps on adding the data but do not show it. Breakpoint shows the call to reloadData is not invoking cellForRowAtIndexPath after that.
What could be the reason.
hunch: make sure you message UIKit objects from the main thread (exclusively).
In my UIView I've got a UITableView (UITV) which is controlled by an NSFetchedResultsController (NSFRC). The UIView is inside a UINavigationController.
When the view is about to be loaded/displayed I start some background activities which fetch data from a remote server (JSON) and parse into Core Data.
The NSFRC is being called when the parsing is done and the threaded NSManagedObjectContext have been merged into the main context.
The problem is that sometimes many rows are being inserted to Core Data at once, a lot of table cells are being added and there is quite a delay from that the actual fetching and parsing is done, until the rows are being displayed.
Now I wonder if anyone knows of any solution to, for example:
hook up a spinner to some "fetched results controller inserted all its rows for this time" (or something) notification/delegate call to at least tell the user that "something is going to show up soon"?
Or might the best solution simply be to not initialize the NSFRC until the background fetching and processing is completed?
Thanks!
If I understand your question correctly, you may want to look into the NSFetchedResultsControllerDelegate methods, with documentation available here: http://developer.apple.com/library/ios/#documentation/CoreData/Reference/NSFetchedResultsControllerDelegate_Protocol/Reference/Reference.html
There are delegate methods available for pre changes with controllerWillChangeContent:, post changes with controllerDidChangeContent and during changes with didChangeSection: and didChangeObject.
I hope it helps!
Rog
I am trying to load a table view from a cache very quickly and have the cached data in the table view appear. Then I want download new data, and then reload the table. Right now I am downloading the new data on viewDidAppear, but the view still refreshes before it displays. Any idea how I can do this?
viewDidAppear is not a good place to download data; it is really intended for clean up after presenting data, so I can understand why you used it. You should request your data reload as early as possible, such as in viewDidLoad or viewWillAppear (depending on your reuse or otherwise of view controllers).
If you are doing asynchronous downloads, which you should be, put the reloadData call in your delegate callback function for when the data is completed.
Simply calling [tableView reloadData] after the download might do the trick. This will trigger a refresh of your table cells.
To download the new data, you may consider using Cocoa Streams, particular an asynchronous Socket Stream. In the stream delegate, call reloadData when the download is completed.
I ended up implementing the delegate class to do this asynchronously. This example was extremely helpful, and I implemented much of its code:
http://developer.apple.com/iphone/library/samplecode/URLCache/Introduction/Intro.html#//apple_ref/doc/uid/DTS40008061-Intro-DontLinkElementID_2
I have a UITableView subclass and a UITableViewCell subclass that I'm using for cells. I'm bulding all my cells in advance and store them in an array from where I use them in cellForRowAtIndexPath. Aside from this I have a thread that loads some images in each cell, in the background. The problem is that the cells don't get refreshed as fast as the images are loaded. For example, if I don't scroll my table view, the first cells only get refreshed when all cells have been modified and the thread has exited.
Any ideas on how I can effectively refresh my tableview/cell?
Have you tried calling [cell setNeedsDisplay] but on the main thread?
setNeedsDisplay when called on a background thread does pretty much nothing,
try this:
[cell performSelectorOnMainThread:#selector(setNeedsDisplay) withObject:nil waitUntilDone:NO];
Are you using a callback to notify the controller of your tableview that the images have been loaded? If not, that would be an ideal method.
When the image loads, fire off a callback to the table view controller that sets the image on the cell, and then calls reloadData on the tableView.
This way whenever a new image loads, the table will update to display it.
Not sure exactly what you are trying to achieve with the images - but can I guess they are coming from a server and that is why you want to download them in another thread?
I would not try to load up the cells before you display the table - you should use lazy loading as much as possible to make sure you are making the most of the memory on a device.
My suggestion would be to look at using a subclass of NSOperation to manage the loading of images. Firstly NSOperation will handle all the complexity of threading for you and allow you to queue up the operations. You will then be able to prioritise the operations that you want completed for the cells at the top.
As each operation completes you can make a call back to the cell or tableViewController (perhaps create a delegate protocol to make this really easy).
If you have an operation per image/cell combination then you should be able to refresh each cell as the operation completes. Doing this along with prioritising the operations will give you an optimal solution.
If the NSOperations sound complex or you are put off by this - please do try it - it is a lot simpler than I might have made it sound.
Have you tried calling [cell setNeedsDisplay]?