I have to fill a TableView with lots of items (20.000 items frol sqlite) but I know that I will overload it.
Is there a way to load only the needed data when scolling ?
for example if I display 100 items when I scroll over 100 should I load 200 in the table or load only the items 101>200 ?
Also is it possible when returning the Cell content to fetch for EACH element in the embedded sqlite DB ?
Thanks
I have to fill a TableView with lots of items (20.000 items frol sqlite) but I know that I will overload it. Is there a way to load only the needed data when scrolling?
UITableView is designed specifically to load only the cells that are visible. You don't so much "fill" a table as you make the data available to the table via the table's data source. As the table scrolls, it asks its data source for additional cells, and it re-uses the cells that are no longer visible. This minimizes memory usage and maximizes speed. You don't need to do anything to achieve this other than implement the necessary table view data source and delegate methods in your view controller (or some other object).
Also is it possible when returning the Cell content to fetch for EACH element in the embedded sqlite DB ?
Sure, you can do that. Just implement your -tableView:cellForRowAtIndexPath: method to make the appropriate SQLite query for the requested cell.
This the default functionality of a UITableView, it only draws the necessary rows when they need to appear. This is why you have "reusable cells" because they keep getting reused. I think storing the 20,000 items should not be terrible memory overhead, so I would just try using the UITableView default functionality and you will be fine.
Related
I am implementing a chat app using UICollectionView. Initially I fetch only 100 messages. As the user scrolls, I fetch some more messages and then reload the collection view. To maintain the scroll position I set the content offset but scrolling gets stopped. How to maintain the scrolling speed after reloading the UICollectionView so user doesn't feel jerk?
You could try to use the prefetchDataSource that was introduced in iOS10.
UICollectionView Prefetch Data Source in iOS 10?
There're several approaches to handle this.
You don't use reloadData() but rather insertItemsAtIndexPaths:, that way you don't have rebuild the whole table and only build the items you need.
You load additional data when use hits a specific point your collection view. In a willDisplayCell method you can check if indexPath of a cell is getting close to the last index in your data source and load additional rows. In the moment user will scroll to the last item, all the stuff will be already there so you don't have worry.
In my experience the best way is to use both of this approaches combined. Because in general using reloadData() every now and then could be very resourceful depending on your cell layouts.
I have thousands of sections in TableView,and I use titleForHeaderInsection to give each of them a title.But I find that when the TableView is initialized, this method will be called thousands times to give every sections a title. Is that means I should set several sections each time?
No, you don't have to.
A memory is optimised for such occasions, so if your data source is properly set and contains data regardless its size, UI should handle it safely.
UITableView in iOS app, for example, is rendering just those cells, that are displayed at current time. So for example the common tableview on the iPhone 6 is displaying about 15 rows at a time.
And as a user, when you are scrolling down (or up) the table view, each time before the certain cell is displayed, the method cellForRow is called and takes data from your data source.
This also works for sections.
But, if your data don't have to be stored in the App bundle, the best way would be to get source data asynchronously, so for example you get 30 rows from data from server, after launching the app. Then if you reach (by scrolling) 30th row, your app will request more data from server and updates the table.
So user, that won't scroll your tableView, will not download all data and will not use big data transfer.
As a conclusion I would mention, that for all situations, the smaller data source, the better for performance of your app.
Tableview works on concept of reusability so only few which are visible are created and after that rest all are reused so no need to bother about it .
Rest refer to this link : Apple official link : https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/TableView_iPhone/TableViewCells/TableViewCells.html
Go through life cycle of Uitableview datasource methods as each and every method will get called for each section and row. So it is completely fine if section method is called thousand times. If you have any issue for it then add a paging like load first 10 sections and then other 10 sections and go on.
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'm trying to create a custom view that can display a large amount of data, similar to the way UITableView is able to display many rows of data. Right now I'm displaying the data in a UIScrollView, but after I reload the data several times my app starts to receive memory warnings.
What's the right way to design a custom view to display a large amount of data, and how can I avoid these memory warnings?
It doesn't. UITableView loads only as many rows as it can fit on the screen. When it needs more rows it asks the data source for them. This gives the appearance that the table contains all the data without all the overhead of copying everything at once.
When your tableView cell is too heavy means, it has imageView and more than one text label better create a custom cell by subclassing the UITableView.
Make sure that in custom cell the subview should be added only once and reused for cells. Just you need to sent the image of imageview or text of label. Even if you have so many cells in tableview the performance will be good.
And also make sure that if you are loading images from server don't fetch every time when you are setting image for cell. use image cache.
The following link might me useful for loading data to table view from server.
http://www.raywenderlich.com/4295/multithreading-and-grand-central-dispatch-on-ios-for-beginners-tutorial
I have a UITableView that collects data from a database. What I would like to know is if there is some way I can iterate in the UITableView collection and check the values of the cell? The reason I ask is because I would like to update each cell based on the current value that it has (change font, size, color, etc.). I've seen in another SO post regarding this topic, but since the cells are already created and their values are changed it is a bit harder for me. I was thinking of iterating through the UITableView before I call reloadData, but any other suggestions are welcome.
You should not iterate over the cells of UITableView, because some of them (in fact, most of them) may not be present until you request them. UITableView aggressively recycles its cells, so if a cell is not visible, it is very likely that you would be creating it from scratch only to put it back into recycle queue moments later.
Changing your model and calling reloadData the way your post suggests would be the right solution. iOS will ensure that it runs the update in a smallest number of CPU cycles possible, so you do not need to worry about the cells that are already created. This is also the easiest approach in terms of your coding effort.
A table view is for displaying data. The properties of your table cells should only be written to, not read from. The appropriate way of handling this situation would be to update your underlying model objects -- the objects that you use to populate the table view -- as the data changes, and then reload the affected rows.
The issue you'll encounter is that UITableView reuses table cells. Once a table cell scrolls off the screen, it's quite likely that the table view will reuse the same cell to display a different row.
This means it's fundamentally not possible to iterate over the table cells. When you need to refresh a row because its data has changed, you should call reloadRowsAtIndexPaths:withRowAnimation: (or reloadData if all rows have changed) and if the row is visible on screen, UITableView will call your data source methods and give you an opportunity to configure the cell for display.