Transfer from http://www.2cto.com/kf/201308/238449.html
UITableView inherits from Uiscrollview, a scroll-based control that Apple encapsulates for us. The above is mainly a uitableviewcell, you can let UITableViewCell respond to a few click events, you can also add Uitextfield or Uitextview in the UITableViewCell, and other sub-views, Makes it possible to edit text on the cell.
The cell in the UITableView can have a lot of memory, typically by reusing the cell: by specifying a reuse identifier (reuseidentifier) for each cell, which specifies the kind of cell, when the cell rolls out of the screen, The cells that are scrolled out of the screen are placed in the reused queue, and the cells are removed from the queue for reuse when a cell is not displayed on the screen.
But for a mutable custom cell, sometimes this reuse mechanism goes wrong. For example, when a cell contains a subclass of Uitextfield and is placed in the reuse queue for reuse, if a cell that does not contain any child views is to be displayed on the screen, it will be taken out and displayed in a cell with no child views, using the cell that is reused. It's going to go wrong.
Workaround:
Method 1 will get the cell's method from-(uitableviewcell*) Dequeuereusablecellwithidentifier: (nsstring*) identifier for-(UITableViewCell *) Cellforrowatindexpath: (Nsindexpath *) Indexpath
The reuse mechanism calls the Dequeuereusablecellwithidentifier method, which means "dequeue a reusable Cell", So just swap it for cellforrowatindexpath (remove the cell only from the row of the cell you want to update), you can use no reuse mechanism, so the problem can be solved, although some space may be wasted.
Example code:
[Plain]
-(UITableViewCell *) TableView: (UITableView *) TableView Cellforrowatindexpath: (Nsindexpath *) Indexpath
{
static NSString *cellidentifier = @ "Cell";
UITableViewCell *cell = [TableView dequeuereusablecellwithidentifier:cellidentifier]; Change to the following method
UITableViewCell *cell = [TableView Cellforrowatindexpath:indexpath]; Take a row exactly as Indexpath, rather than removing it from the 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 to the following method
UITableViewCell *cell = [TableView Cellforrowatindexpath:indexpath]; Take a row exactly as Indexpath, rather than removing it from the cell reuse queue
if (cell = = nil) {
cell = [[UITableViewCell alloc] Initwithstyle:uitableviewcellstyledefault reuseidentifier:cellidentifier];
}
//... Other code
}
Method 2 is addressed by specifying a different reuse identifier (reuseidentifier) for each cell.
The reuse mechanism is to reuse cells based on the same identifiers, and cells with different identifiers cannot be reused by each other. So we can avoid the problem of different cell reuse by setting the identifier of each cell to be different.
Example code:
[Plain]
-(UITableViewCell *) TableView: (UITableView *) TableView Cellforrowatindexpath: (Nsindexpath *) Indexpath
{
nsstring *cellidentifier = [NSString stringwithformat:@ "cell%d%d", [Indexpath section], [Indexpath row]];//to Indexpath to uniquely determine Cell
UITableViewCell *cell = [TableView dequeuereusablecellwithidentifier:cellidentifier]; DEQUEUE the Reusable cell
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%d", [Indexpath section], [Indexpath row]];// Uniquely identify the cell with Indexpath.
UITableViewCell *cell = [TableView dequeuereusablecellwithidentifier:cellidentifier]; DEQUEUE a reusable cell
if (cell = = nil) {
cell = [[UITableViewCell alloc] Initwithstyle:uitableviewcellstyledefault reuseidentifier:cellidentifier];
}
//... Other code
}
Method 3 Removes all child views that reuse a cell
This approach is done by removing all the child views of the reused cell, resulting in a cell that has no special format for reuse by other cells.
Example code:
[Plain]
-(UITableViewCell *) TableView: (UITableView *) TableView Cellforrowatindexpath: (Nsindexpath *) Indexpath
{
static NSString *cellidentifier = @ "Cell";
UITableViewCell *cell = [TableView dequeuereusablecellwithidentifier:cellidentifier]; DEQUEUE a reusable cell
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
}
UITableView Cell Reuse identity