I'm developing an iOS application in which i have a UITableView containing list of people coming from web-service and i have a more button on bottom. When user clicks on more it calls a service which provides some new people for the list. Now i want to add this list with the previous tableView list without reloading the whole tableView. how do i achieve this.
Any help would be really appreciable. I can provide my code of more button where i'm calling the service to get the data from service.
UITableview provides several APIs for manipulating the content. You should use the
- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation: (UITableViewRowAnimation)animation;
method. The way how they should be applied is described in the Table View Programming Guide.
Practically, when the button is clicked, you start the network request for the list of names and when that finishes, you add the rows to the table with the above API.
Note: as long as you do only this modification to the table view, you don't have to use the beginUpdates, endUpdates methods. If there are multilple changes carried out at once (deletion, addition, reordering) then the beginUpdates/endUpdates is necessary.
Have a look at UITableView's - beginUpdates; and - endUpdates method.
In between calling these you'd have to insert the rows into the table view. If you are using UITableView's - insertRowsAtIndexPaths:withRowAnimation: method you can even skip the begin- and endUpdates.
Make sure to insert your new objects to your data source object before calling insertRowsAtIndexPaths:withRowAnimation:.
If you don;t want to reload the table then, at least, you have to call
insertRowsAtIndexPaths: withRowAnimation:
except that you can't show the newly added data in your table view.
As per my experience , It is not possible to add/display new names to table view without reloading it.
But you can achieve your task as follows ;
You can set arraCount(one varaible) for namesArray count. After calling webservice, you can increment arrayCount varaiable and reload the table view , which will display new added names in the table.
Hope this will help.
Related
I have made an uitableView and I am fetching data from json from a webservice
now i want that I get first 20 object first and load it in my tableView. it is happening properly
Now I want that when user scroll to the footer ..next 20 data should be fetched and it should be shown in tableView..
I am stuck here ..can anyone give me any idea how to proceed next?
May be you can put Load more button in footerview and by tapping that you can load another 20 records from server ?
Another method is to implement Pull To Refresh and modify it as per your need.
You can use a ready made implementation of a UITableView with pull-to-refresh functionality.
Have a look at EGOTableViewPullRefresh or for a simpler implementation to PullToRefresh.
If you are interested in implementing this yourself, one approach is to add a subview to your UITableView (e.g., UILabel showing the "pull to refresh" message); then "intercept" the delegate methods when the user scrolls down (or up) and calculate whether the subview came into the viewable frame. Then issue the reload.
Another approach would be adding a last row to your table; then when the tableView:cellForRowAtIndexPath: method of your data source is called, return a cell with the "pull to refresh" message and do the refresh.
But you will be better off using one of the suggested implementations.
To know if you reached the button of the table (aka: seeing the footer) I think you could use this:
How to know when UITableView did scroll to bottom in iPhone
I am making a simple gaming app, implementing a tab bar controller. The second tab, or high score page is what I am having problems with. I am able to populate the UITableView with an initial array of objects, however I can't seem to add new cells. Now I read about User entered cells, but how exactly would I extract the winner from one tab to populate the UITableView in the high score tab? Thank you for your time!
For adding new cells to your UITableView, the most straightforward way would be by simply reloading the entire table view [UITableView reloadData].
Assuming that you are storing the cell-contents in a mutable array, simply add those new entries to that array and reload the table.
You can update your array and call reloadData on table view to reload it and also if you want to add cell at a specific position you can use
(void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:
When calling reloadData on a UITableView what methods are actually invoked?
[tableView reloadData];
The whole table view is reloaded, it calls cellForRowAtIndexPath to get the cells for all your rows and sections...doing so it also calls numberOfSections method of tableView datasource and numberOfRows method of tableview data source etc etc
Also, for future reference, that information is readily available in the documentation here. Copy/pasted from Apple's documentation:
Call this method to 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. It should not be called in the methods that insert or delete rows, especially within an animation block implemented with calls to beginUpdates and endUpdates
For the accept answer is very good. But I want to mention all the visible cells will be recreated. Usually this not a big deal. But if your tableViewCell stored property contains some data might be lost.
For example, click a button on a tableViewCell to request some data from internet and saved the retrieved data to a stored property. If you reloadData, then the retrieved data will lost. Of course this is not a proper actually make a request from tableViewCell. But just want to explain this situation.
After rendering a UITableView with a given datasource, I want to be able to switch to a different one prior to calling reloadData.
Tried doing it in the method
- (void)viewDidAppear:(BOOL)animated;
but as far as I can see this isn't called when all the visible cells are rendered.
By placing a breakpoint it seems as if nothing is actually rendered. So I must have misunderstood its actual purpose.
Is there a API callback for that or do I have to programmatically look for it?
e.g. in
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
when indexPath holds the index for the last rendered cell in the tableview.
To put it into perspective (somewhat).
Suppose we have a UITableView which has a "static" datasource. Once all the static data is displayed, you want to switch to a dynamic datasource which fetches the data off the internet and reloads each row as fetched.
So I'm actually looking for the "right hook" in which to make that change from one datasource to the other.
Are there any other issues one should be concerned about?
Further clarification. I have written all the required code (e.g. an UITableViewController with the static data initialized, different datasources, background threads for the dynamic views, a delegate to notify the UITableViewController as new data is coming in) what I haven't figured out (what the question is all about) is when to actually make the switch from one datasource to the next.
When you call reloadData it forces your UITableView to re-query your data source regardless of the amount of data that is already loaded. Also, the cells that are not visible are not being loaded, so practically the last cell is only filled with data if and when you scroll down to it. If you know for sure that all your cells are visible at once, as you might have a small number of them, you might do as you suggested and call your update function when indexPath holds the index for the last cell in the tableview.
Edit:
In the light of your edits, I'm thinking that perhaps the moment you should switch data sources depends on the state of your "live" data - when you've got enough data in it to be able to show enough of it on the screen. That is, let the static data be displayed, and only switch when you've already fetched a number of values in your live data source.
Another idea might be keeping only one mutable data source, with pre-loaded static initial data. As you fetch new "live" values, you start by replacing the ones that you already have, and then continue adding new values if their number exceeds the initial number of static entries.
viewDidAppear is all about the view controller, not the table. The table reloading will never call that method.
What you want to do, is better handled either via a delegate approach or using notifications. Set up the static data set in viewDidLoad, but then right away start the background dynamic data fetch. When that fetch is complete, have the code downloading the new data call you either as a delegate, or issue a notification your the view controller with the table listens to, and reset the table view data - then you can simply call reloadData, and the cellForRow:AtIndexPath: method will be called again for the rows on the screen (reload data will also revert back to the top of the table).
UITableView load the cells lazy, in other means it only loads the cells that are visible to the user. When the user then scrolls down, the table view will load the new cells while the "old" cells will be released. There are ways to load the entire data source, but this is not recommended from Apple - since it will be heavy on the memory load of the iPhone.
viewDidAppear() is probably your best bet.
The viewWillAppear: and viewDidAppear: methods are only called when your UIViewController gets pushed on the screen (e.g. by an UINavigationContoller or UITableViewController).
What I would do in your situation is to call a method on your own view controller when your dynamic data source is ready (or whenever you intend to change the data source). In this method set the data source and then call [[self tableView] reloadData];
What you should look out for is, if you are constructing your dynamic data source in the background (which I suppose you do) then you need to call your method on the main thread using performSelectorOnMainThread:
I have built a UITableView with custom cells which each contain 5 textfields (a bit like a grid). The cells can be edited inline (no need to go in a separate view).
I am faced with some wierd defects when it comes to using reloadData.
my table footer is dynamic (calculates a value based on the cells). Should I call reloadData everytime I update a cell ? Or is there a way for the footer only to be updated?
When I start editing my cell but leave it empty (do not write any text in the textfield), the cell does not move to edit mode if I have used reloadData. Is there any known defect when doing reloadData on empty cells?
Basically I am not really sure on the best practices to use reloadData and did not find any guide anywhere. Any advice would be very much appreciated.
Regards,
Jonathan
You should minimize reloads in tableviews, and use it only when you cannot update the table other way.
For example when deleting a row you do not need a reload, just use deleteRowsAtIndexPaths or deleteSections as needed.
Other views you can just update their properties. For example if you have a label in the footer, you just need to set its text property. You do not need a table reload.
I think you cannot edit directly some properties of the cells outside cellForRowAtIndexPath method. In cases like this you will need a table reload that will call cellForRowAtIndexPath method.