Solution to duplicate content due to Cell reuse mechanism in UITableView

Source: Internet
Author: User

UITableView inherits from UIScrollview, which is a scroll-based control encapsulated by Apple. UITableViewCell is used to respond to click events. You can also add sub-views such as UITextField or UITextView to UITableViewCell to edit the text on the cell.


There can be many cells in UITableView. Generally, cell can be reused to save memory. by specifying a reuseIdentifier for each cell, you can specify the cell type, when the cell is out of the screen, it will put the cell out of the screen into the reused queue. When a cell not on the screen is to be displayed, the cell is retrieved from the queue for reuse.

However, for a variable custom cell, this reuse mechanism sometimes fails. For example, when a cell contains a subclass of UITextField and is placed in the reused queue for reuse, if a cell without any sub-view is displayed on the screen, the reused cell is retrieved and displayed in the cell without any sub-view. In this case, an error occurs.

Solution:

Method 1: Change the cell obtaining method from-(UITableViewCell *) dequeueReusableCellWithIdentifier :( NSString *) identifier to-(UITableViewCell *) cellForRowAtIndexPath :( NSIndexPath *) indexPath

The reuse mechanism calls the dequeueReusableCellWithIdentifier method, which means "reusable cell columns ", therefore, you only need to replace it with cellForRowAtIndexPath (retrieve the cell from the row of the cell to be updated), and the reuse mechanism is not used, so the problem can be solved, although it may waste some space.

Sample Code:


[Plain]
-(UITableViewCell *) tableView :( UITableView *) tableView cellForRowAtIndexPath :( NSIndexPath *) indexPath
{
Static NSString * CellIdentifier = @ "Cell ";
// UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: CellIdentifier]; // change it to the following method:
UITableViewCell * cell = [tableView cellForRowAtIndexPath: indexPath]; // retrieve a row accurately based on indexPath instead of from cell reuse queue
If (cell = nil ){
Cell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier: CellIdentifier];
}
//... Other code
}

-(UITableViewCell *) tableView :( UITableView *) tableView cellForRowAtIndexPath :( NSIndexPath *) indexPath
{
Static NSString * CellIdentifier = @ "Cell ";
// UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: CellIdentifier]; // change it to the following method:
UITableViewCell * cell = [tableView cellForRowAtIndexPath: indexPath]; // retrieve a row accurately based on indexPath instead of from cell reuse queue
If (cell = nil ){
Cell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier: CellIdentifier];
}
//... Other code
}

 

 

 

Method 2: specify a reuseIdentifier for each cell.
The reuse mechanism is to reuse cells based on the same identifiers. Cells with different identifiers cannot reuse each other. Therefore, we can set the identifiers of each cell to be different to avoid reuse of different cells.

Sample Code:


[Plain]
-(UITableViewCell *) tableView :( UITableView *) tableView cellForRowAtIndexPath :( NSIndexPath *) indexPath
{

NSString * CellIdentifier = [NSString stringWithFormat: @ "Cell % d", [indexPath section], [indexPath row]; // use indexPath to uniquely determine the cell
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: CellIdentifier]; // cell with reusable Columns
If (cell = nil ){
Cell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier: CellIdentifier];
}
//... Other code
}

-(UITableViewCell *) tableView :( UITableView *) tableView cellForRowAtIndexPath :( NSIndexPath *) indexPath
{

NSString * CellIdentifier = [NSString stringWithFormat: @ "Cell % d", [indexPath section], [indexPath row]; // use indexPath to uniquely determine the cell
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: CellIdentifier]; // cell with reusable Columns
If (cell = nil ){
Cell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier: CellIdentifier];
}
//... Other code
}

Method 3 Delete all child views of the reused cell

This method deletes all the child views of the reused cell to obtain a cell with no special format for reuse by other cells.

Sample Code:


[Plain]
-(UITableViewCell *) tableView :( UITableView *) tableView cellForRowAtIndexPath :( NSIndexPath *) indexPath
{
Static NSString * CellIdentifier = @ "Cell ";
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: CellIdentifier]; // cell with reusable Columns
If (cell = nil ){
Cell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier: CellIdentifier];
}
Else
{
// Delete all child views of a cell
While ([cell. contentView. subviews lastObject]! = Nil)
{
[(UIView *) [cell. contentView. subviews lastObject] removeFromSuperview];
}
}
//... Other code
}

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.