Preload cells of uitableview

2020-07-06 08:18发布

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 to preload 10 cells. Is this possible?

5条回答
冷血范
2楼-- · 2020-07-06 08:44

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.

查看更多
爷的心禁止访问
3楼-- · 2020-07-06 08:50

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.

查看更多
在下西门庆
4楼-- · 2020-07-06 08:53

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

查看更多
Animai°情兽
5楼-- · 2020-07-06 08:58

Change the dequeueReusableCellWithIdentifier when you are reusing the table view otherwise it will load the old data

查看更多
Fickle 薄情
6楼-- · 2020-07-06 09:00

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.

查看更多
登录 后发表回答