My UITableViewCells can accept input of data. While working in one cell, it would be perfectly natural for the user to want to scroll up, check something in another cell, then return to the first cell and continue the data entry.

The problem is that this will frequently cause the UITableView to recycle the cell, which wreaks havoc in my program.

Is there any way to temporarily tell iOS not to recycle the cell?

Once the data entry is done, I am fine if it is recycled.

I should add that the data entry uses a custom keyboard. So first responder status is not an issue.

有帮助吗?

解决方案

As Chiefly Izzy said, it's not a common way to work. And going against the way the lists work may cause problems. If you want to reduce your problem, keep the content of your cell in memory and use this saved content to refill the cell when willDisplayCell is called instead of rebuilding the whole thing from start each time.

其他提示

Give a different cellIdentifier to the cells that are significantly different. If the cell at the bottom has its own identifier, then when the user scrolls to the bottom, it won't recycle your cell from the top. However, this will still preserve your cell at the top in the reuse queue, so that when you scroll back to the top, you won't need to recreate it.

There's no way how to prevent cell recycling if you do use dequeueReusableCellWithIdentifier: method of UITableView in a common way.

If you would like to do this, you should implement it on your own in UITableView's data source protocol method - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath.

Gendolkari's solution gave me an idea for temporarily removing a cell from the dequeue cycle. It does involve setting a read-only value using KVC, so it's not for the truly hack-adverse.

When you first want to remove the cell from the cycle, change the reuseIdentifier for that particular cell. We want to be able to find the cell later so rename it something that we can index against. I found [NSIndexPath description] to be useful here. The reuseIdentifier is a read-only property, but this is Objective-C, and we have KVC:

[cell setValue:[[self.tableView indexPathForCell:cell] description] forKey:@"reuseIdentifier"];

Now whenever we reuse a cell in the cellForRowAtIndexPath:

UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"cellIdentifier"];

we won't get back this particular cell because we have changed the reuseIdentifier.

However, if we scroll down then scroll back up, we probably want to display the original cell that we removed from the dequeue cycle. To do this when we are reusing a cell first attempt to dequeue a cell based on indexPath, and if we can't find that attempt to dequeue a cell simply based on the basic cell identifier string:

UITableViewCell *cell;
cell = [self.tableView dequeueReusableCellWithIdentifier:[indexPath description]];
if (!cell) cell = [self.tableView dequeueReusableCellWithIdentifier:@"cellIdentifier"];

When you want to put that cell back into the dequeue cycle, simply change the reuseIdentifier back to the original value:

[cell setValue:@"cellIdentifier" forKey:@"reuseIdentifier"];
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top