I acknowledge that UITableview load dynamically a cell when user scrolls. I wonder if there is a way to preload all cells in order not to load each one while scrolling. I need t
You can initialize table view cells, put them into an array precomputedCells
and in the data source delegate method tableView:cellForRowAtIndexPath:
return the precomputed cells from the array instead of calling dequeueReusableCellWithIdentifier:
. (Similar to what you would do in a static table view.)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
return [self.precomputedCells objectAtIndex:indexPath.row];
}
It might also be useful to have a look at the WWDC 2012 Session 211 "Building Concurrent User Interfaces on iOS" where it is shown how to fill the contents of table view cells in background threads while keeping the user interface responsive.
Solution for autoresizing cells. Change 'estimatedRowHeight' to lower value
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = 32; //Actual is 64
}
Actual estimated height is 64. 32 is used to add more cells for reuse to avoid lagging when scrolling begins
Change the dequeueReusableCellWithIdentifier when you are reusing the table view otherwise it will load the old data
As suggested by Mark I also changed the height of my UITableView temporarily so that the table view creates enough reusable cells. Then I reset the height of my table view so that it stops creating reusable cells while scrolling.
To accomplish that I create a helper bool which is set to false by default:
var didPreloadCells = false
It is set to true when my table view first reloaded data and therefore created the first reusable cells.
resultsHandler.doSearch { (resultDict, error) -> Void in
[...]
self.tableView.reloadData()
self.didPreloadCells = true
[...]
}
The real trick happens in my viewDidLayoutSubviews Method. Here I set the frame of my table view depending on my boolean. If the reusable cells were not created yet I increase the frame of the table view. In the other case I set the normal frame
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.tableView.frame = self.view.bounds
if !didPreloadCells
{
self.tableView.frame.size.height += ResultCellHeight
}
}
With the help of that the table view creates more initial reusable cells than normal and the scrolling is smooth and fluent because no additional cells need to be created.
I was looking for a solution to the original question and I thought I'd share my solution.
In my case, I only needed to preload the next cell (I won't go into the reason why, but there was a good reason).
It seems the UITableView renders as many cells as will fit into the UITableView frame assigned to it.
Therefore, I oversized the UITableView frame by the height of 1 extra cell, pushing the oversized region offscreen (or it could be into a clipped UIView if needed). Of course, this would now mean that when I scrolled the table view, the last cell wouldn't be visible (because the UITableView frame is bigger than it's superview). Therefore I added an additional UIView to the tableFooterView of the height of a cell. This means that when the table is scrolled to the bottom, the last cells sits nicely at the bottom of it's superview, while the added tableFooterView remains offscreen.
This can of course be applied to any number of cells. It should even be possible to apply it to preload ALL cells if needed by oversizing the UITableView frame to the contentSize iOS originally calculates, then adding a tableFooterView of the same size.
Hopefully this helps someone else with the same problem.