The UITableView's data source is from an external server. Anyone could update / delete / add data to it at any time.
The problem is that UITableView likes to complain whenever data is not consistent:
The number of rows contained in an existing section after the update (X) must be equal to the number of rows contained in that section before the update (Y), plus or minus the number of rows inserted or deleted from that section and plus or minus the number
How do I create a UITableView that lets me delete, add, update and refresh without having to be consistent?
I use Swift 3.
"How do I create a UITableView that lets me delete, add, update, and refresh without having to be consistent?"
You don't. The model data presented in the table view must match the table view itself. If you delete cells from the table view, you have to delete those entries in your model so that when the table view asks the data source for info on your rows/sections, they match.
You should cache your server data locally and use it to populate the table view. If the user makes a change to the local copy, you should batch-update the server with your changes.
Likewise, if the server updates the data, you should batch-update the local copy and then tell the table view to reload it's contents.
It's hard to give a specific answer without a more specific description of what you're trying to do.
Related
I have a table view which populates from an array of strings. Using UIGestureRecognizer users can reorder the cells and save the new order.
When pressing Save I need the new order of the cells to save to the array. I have tried many different techniques without success.
How can I capture all the current cell texts in order?
Don't rely on the cell contents as your data source. When the user reorders the cells, update your backing array to match (or a copy of it if you need to be able to revert changes).
That way, when you want to save, everything is already in the correct order.
I have a loop that runs through all of a user's address book contacts. It checks to see if any of the user's contact's phone numbers are in my server's database. The database returns an object to me that has a count property, and if the phone number was found in the database, then the object returns with a count of 1.
I need to add code to this loop, so that any time the object returns with a count of 1, a new cell and row are added to the UITableView that has already been created in the story board.
I have some method implementations already setup to control the UITableView but I can only get them to work for 1 contact and that is it. These were copied from a tutorial and I just can't get them to work for my specific purpose. I have also played around with some code from the iOS docs but I'm lost.
Isn't there a simple way to programmatically add additional cells and rows to a UITableView that has already been created in the storyboard?
If you want to add dynamic row then the simplest way to add new data in array in which yo have store data for creating rows and then call for reload of table, it will add new rows in you table.
I am using a FetchedResultsController to fetch the data for my UITableView. The data is created via actions performed on another tab (so my table may have 5 items but if I switched tabs and go back to my table, it may have more than 5 items that it should display). My table can potentially contain many rows. Right now I am using [myFetchedResultsController performFetch] in my viewDidLoad.It appears that when I create data in my other tab, when I switch back to my table tab, that new data is put into my table automatically without me perfomring [myFetchedResultsController performFetch] again. Here are my questions:
1) Does a fetchedResultsController automatically monitor the manajedObjectContext for changes and fetches the new objects if they come into existence? (This appears to be what is happening but I just want to make sure. Perhaps I have some code that is helping me do this that I forgot I put in somewhere)
2) Does the fetch performed by [myFetchedResultsController performFetch] fetch all of the objects at that time, or does it fetch only what it can fit in the view of the table and it fetches the rest later as it needs it (as you scroll in the table)? I ask because since my table can potentially have a lot of rows, it seems inefficient to fetch all the data at once if only ~12 of them will be displayed on the table at once.
EDIT: I just realized that in my FetchedResultsController delegate methods, I have
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
[self.tableView reloadData];
}
Am I correct in saying that a fetchedResultsController monitors for change, but will not apply it to the table unless the table is reloaded as I have done? If so, then I have another question about UITableView. Does reloading the table only reload the rows in view and then the other rows are updated as you scroll? Again I ask because if my data is very large, it seems inefficient to reload the entire table if it will reload all rows at once.
Yes, if you add a delegate
You should set the fetch request batch size when you configure the FRC because it can only load an appropriate number of items for the screen if you tell it how many that is.
You apply the changes, the FRC just collects and supplies the data. The delegate method tells you about a change. Reloading affects the whole table in terms of row count but only shows the visible rows (assuming the batch size is set appropriately).
I have an indexed table view in which the cells are grouped alphabetically into sections. I would like to be able to only load a block of the data associated with a particular section when that indexed section is selected. In other words, my table view is the type where there is a selectable field at the right side of the table view that contains the letters A-Z. You can select the letter P for example to jump to cells that have content that starts with the letter P.
Is there any way to detect the selection of an indexed section so that I can then reload the cells in that section once I load the block of data associated with that section?
As the user uses the index down the side, the UITableViewDataSource tableView:sectionForSectionIndexTitle:atIndex: method will be called.
You can add logic to this method that if this is the first time you've seen a given section index, that you need to load the data for the section.
But keep in mind that long before this you would have already told the table how many total sections there are and how many rows are in each of those sections. So long before your table even shows the index down the side, you need to have at least loaded counts for all of the sections but not necessarily the detailed data.
Also keep in mind that a user can slide their finger down the index list. This means the table will want to jump to each and every section as the user slides their finger. So whatever lazy loading you do needs to deal with this in a nice manner (not making the UI sluggish).
I've a UITableViewDataSource which maintains sections of data items which will be presented by an UITableView instance. The table view is editable, allowing insertion and deletion of rows and sections, and all changes on the view should be written back to the data source. After reading through the Apple documents, I can deal with insertion and deletion on rows by sending message tableView:commitEditingStyle:forRowAtIndexPath: to the data source.
But, however, I can't figure out what is the standard way to feedback the changes on sections to the data source. Please kindly help.
The delegate method tableView:commitEditingStyle:forRowAtIndexPath: is called by the table view to tell you what the user has done (what they have added / removed). It is then the responsibility of your code to make the appropriate changes to your Model and reload the table view.
The simplest way to reload is to call reloadData, and you also have more specific options for reloading / inserting / removing individual rows or sections - this is all from a UI perspective and the table view requires that you have updated your Model before you call any of these methods or the table view will throw an exception.