滚动时 UITableView 中的数据重复
Posted
技术标签:
【中文标题】滚动时 UITableView 中的数据重复【英文标题】:Data repeat in UITableView when scrolling 【发布时间】:2013-07-04 10:09:26 【问题描述】:我使用下面的代码在 TableView 上显示数据,但是在滚动时,数据重复和其他数据丢失。
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
return 1;
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
return [FileCompletedArray count];
cellForRowatindexpath():
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
static NSString *CellIdentifier = @"CellIdentifier";
UITableViewCell *cell = [_tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
UILabel *FileNameLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 0, 100, 30)];
FileNameLabel.backgroundColor = [UIColor clearColor];
FileNameLabel.font = [UIFont fontWithName:@"Helvetica" size:16];
FileNameLabel.font = [UIFont boldSystemFontOfSize:16];
FileNameLabel.textColor = [UIColor blackColor];
NSLog(@"Reseversed TEMP array %@",FileCompletedArray);
FileNameLabel.text =[FileCompletedArray objectAtIndex:indexPath.row];
[cell.contentView addSubview: FileNameLabel];
[FileNameLabel release];
return cell;
你有什么解决办法吗?提前致谢
【问题讨论】:
【参考方案1】:使用不同的单元格标识符
例如像下面这样...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
NSString *CellIdentifier = [NSString stringWithFormat:@"%d,%d",indexPath.section,indexPath.row];
UITableViewCell *cell = [_tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
/// write your code here..
OR 设置nil
如下所示..
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
//static NSString *CellIdentifier = @"CellIdentifier";
UITableViewCell *cell = [_tableView dequeueReusableCellWithIdentifier:nil];
if (cell == nil)
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil] autorelease];
/// write your code here..
【讨论】:
虽然这是解决方案之一,但我认为cell
不会被这段代码重用。每次它都会创建一个新的cell
。
这段代码不会重复使用单元格,而是每次都创建新的单元格。如果数据源很大,这将产生性能问题。此外,不重用单元格也不是一个好的编码习惯。
不,这不是问题,当您有大量数据时,您可以使用客户单元的可重用性.. :)
这段代码使单元格重用变得不可能。这是错误的。没有人嫉妒……
@vikingosegundo no mate 不仅因为这个答案,而且在我给出答案之后的某个时候,有人无缘无故地对我投了反对票.. 同样在这里你是对的,对于许多记录这种方法不好但是为此,我使用我的一种自定义方法来克服这个问题。如果出现问题,我会发布 Mate .. :)【参考方案2】:
这个问题是因为你的UITableView
Reuse Cell 瞬间创建新的。
我给你一些建议,可能对你有帮助。
1) 在两者之间添加Controller
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
/// Your code of initialization of controller;
/// set property of controllers such like (Text UILabel, image of UIImageView...etc) .
return cell;
1) 将您的Controller
添加到cell.contentView.
已编辑:
在您关注我的编辑答案之前,我想告诉您以下代码不利于内存管理,因为它会为UITableView
的每一行创建新单元格,所以要小心。
但是如果UITableView
有限制行大约(50-100 可能是)os 使用以下代码,如果它适合您,则更好。
NSString *CellIdentifier = [NSString stringWithFormat:@"S%1dR%1d",indexPath.section,indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
/// Your whole code of controllers;
【讨论】:
【参考方案3】:您仅在创建新单元格时设置标签的文本。但是,在单元重用期间,不会创建新单元。因此,您设置/更改文本的代码不起作用。您可以使用此修改后的代码。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
static NSString *CellIdentifier = @"CellIdentifier";
UITableViewCell *cell = [_tableView dequeueReusableCellWithIdentifier:CellIdentifier];
UILabel *FileNameLabel=nil;
if (cell == nil)
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
FileNameLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 0, 100, 30)];
FileNameLabel.tag = 1001;
FileNameLabel.backgroundColor = [UIColor clearColor];
FileNameLabel.font = [UIFont fontWithName:@"Helvetica" size:16];
FileNameLabel.font = [UIFont boldSystemFontOfSize:16];
FileNameLabel.textColor = [UIColor blackColor];
[cell.contentView addSubview: FileNameLabel];
[FileNameLabel release];
if(!FileNameLabel)
FileNameLabel = [cell.contentView viewWithTag:1001];
FileNameLabel.text =[FileCompletedArray objectAtIndex:indexPath.row];
return cell;
您也可以使用默认的textLabel
而不是创建和添加新标签
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
static NSString *CellIdentifier = @"CellIdentifier";
UITableViewCell *cell = [_tableView dequeueReusableCellWithIdentifier:CellIdentifier];
UILabel *FileNameLabel=nil;
if (cell == nil)
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell.textLabel.font = [UIFont fontWithName:@"Helvetica" size:16];
cell.textLabel.font = [UIFont boldSystemFontOfSize:16];
cell.textLabel.textColor = [UIColor blackColor];
cell.textLabel.text =[FileCompletedArray objectAtIndex:indexPath.row];
return cell;
【讨论】:
【参考方案4】:我也遇到了同样的问题,当我们重用单元格时会出现问题。在重用数据时,其中已经存在数据,我们还编写了更多数据,为了解决这个问题,我对我的表视图委托方法 cellForRowAtIndexPath 做了一个小的改动。这里我使用的代码总是使用表格视图。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
if (!cell)
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"cell"];
for (UIView *view in cell.contentView.subviews)
[view removeFromSuperview];
return cell;
for 循环在我们重用某个单元格时执行,它的作用是删除 UITableViewCell 中存在的所有先前数据
希望这会对某人有所帮助。
【讨论】:
以上是关于滚动时 UITableView 中的数据重复的主要内容,如果未能解决你的问题,请参考以下文章
未分配给父 UIViewController 视图属性时,UITableView 不滚动