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.
Related
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.
I want to loop through a TableView and extract the text from all the selected rows. I suppose I "could" create and maintain a special array that is updated every time a row is selected/deselected using the didSelect/didDeselectRowAtIndexPath methods. But creating a separate array seems like an extra step. Is there no way to let the TableView itself serve as the array and then simply loop through it and get the selected rows? What would the code look like? I'm new to Swift, so this might be a silly question.
Part of the problem is that cells are supposed to be reused, and when used this way it is not possible to loop through them all. You could get around this by using a unique reuse identifier for each cell, such as the indexPath itself or some underlying unique id in your model. Then, you could indeed loop through all cells and retrieve whatever state you desired from each.
You would, however, find your application crushed under the weight of too many cells being instantiated and kept in memory. If you don't have many cells you won't be killed, but try it with a big data set and your app will enjoy a very quick death.
It is far more efficient to store one array with a bunch of id's than a large number of memory-intensive UITableViewCells.
As mentioned in comments, you should work with underlying datasource, not the table itself.
For example if your table shows rows from Array, it is way more faster to retrieve strings directly from that array than creating UITableViewCells and get strings from them.
Get indices of selected rows using UITableView's property indexPathsForSelectedRows.
Query datasource for each row.
As has been said the tableview only handles displaying, your datasource is what powers the data shown if you think about it.
Plus as said before the tableview dequeues cells as they scroll on and off the screen.
The best way to achieve what you want is to add a property to your datasource for each element that will allow you to filter out the select properties easily.
How are you storing the state for each selected cell currently? As this is the same functionally you would use to be able to generate your selected text array.
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'm working on an a game app in swift that currently has a tableView displaying the scores, number of trys etc, downloaded in an array from parse.
However, this table can get pretty long if the user plays the game many times. So I'd like to improve the app by displaying the first, say, 20 objects of the array in a tableview, then, once the user scrolls down to the end of the table it automatically adds more rows and displays the next 20 objects in the array (along with the original 20, making the tableview now 40 rows)
If anybody's familiar with the twitter app, that's exactly what I'd like to go for. There's a set amount of tweets shown initially, then once you scroll down to the end of the table more tweets are loaded, in order to decrease loading times.
Problem is, I really have no clue how to implement this at all. I've never been in the situation where I only need to use part of an array. Any help would be greatly appreciated. Dan
UITableView is a virtual view where it calls you back for the data to create cells for a given row that's in view and destroy's cells that go out of view. You should also re-use cells that have been created.
So, I think the answer to your question about pre-loading portions of the list is ... you shouldn't have to. Just implement the data source and answer the data call backs.
More here in the apple docs on the datasource for a UITableView
This is addressed in How to know when UITableView did scroll to bottom in iPhone in Objective-C. If any help needed translating this to Swift, post as a comment and I'll update answer.
EDIT -- The real question:
The tableView delegate methods allow you to perform arbitrary logic / mapping between your data and the table's viewable data. So when you do detect a scroll to the bottom, increment an internal state variable, such as var rowsToReveal declared as a class-wide stored property. After incrementing, call tableView.reloadData(). Then re-write numberOfRowsInSection delegate method to use rowsToReveal rather than someDataArray.count or whatever hardcoded value you had. Make sure rowsToReveal never exceeds the count, of course, otherwise -- instant crash.
I need to show a list of elements from an array in a UITableView (loaded from database).
The steps are:
When I open the view I fetch the data from the database and I store it in the array. If the array has less than 100 objects I perform a call to the backend to get 100 objects.
I show the first 10 objects in the table view while the backend call is performed. If there are less than 10 objects I show them and when the call to the backend is finished, then I show the needed n-objects in order to have 10 in the table.
Now, each time I scroll to the bottom of the table I need to add the next 10 objects from the array, and when the table has 100 objects - don't show more (this is the limit).
Please not that there are might be many possible solutions to this. Some might be better than this.
Create an extra cell with a reuseIdentifier like LoadMoreCell, which should appear at the end of your table.
Implement UITableViewDelegate method tableView:willDisplayCell:forRowAtIndexPath:.
In this check if the reuseIdentifier is LoadMoreCell.
If it is, call your method that requests data.