重复的 UItableViewCell,UITableView 的行
Posted
技术标签:
【中文标题】重复的 UItableViewCell,UITableView 的行【英文标题】:Duplicate UItableViewCell, Rows of UITableView 【发布时间】:2013-01-11 13:30:21 【问题描述】:在上下滚动 2 3 次后,此处的 tableview 将图像添加到所有单元格。代码如下:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
HomeCell *cell = (HomeCell *) [tableView dequeueReusableCellWithIdentifier:@"HomeCell"];
if (cell == nil)
cell = [[HomeCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"HomeCell"] ;
VenueDC *venueObj = [subSubCategoriesArray objectAtIndex:indexPath.row];
cell.lblName.text = venueObj.name;
if ([venueObj.imagesArray count] > 0)
[cell.ivVenue setImage:venueObj.ivVenue];
[cell.ivVenue setHidden:NO];
cell.lblName.frame = CGRectMake(80, cell.lblName.frame.origin.y, 200, cell.lblName.frame.size.height);
venueObj = nil;
return cell;
知道这里发生了什么吗?
图像仅在一个对象中,第一次加载时它会显示一个带有图像的单元格,但滚动后它也会开始在另一个单元格上显示图像。
【问题讨论】:
试试这个线程的答案,可能会对你有所帮助。 :***.com/questions/10535637/… 【参考方案1】:这样解决了,首先我将 lblName 框架设置为其原始位置,因此每次使用单元格时都会重置其位置
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
HomeCell *cell = (HomeCell *) [tableView dequeueReusableCellWithIdentifier:@"HomeCell"];
if (cell == nil)
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"HomeCell" owner:self options:nil];
for (id currentObject in topLevelObjects)
if ([currentObject isKindOfClass:[UITableViewCell class]])
cell = (HomeCell *) currentObject;
break;
VenueDC *venueObj = nil;
venueObj = [subSubCategoriesArray objectAtIndex:indexPath.row];
cell.lblName.text = venueObj.name;
[cell.ivVenue setHidden:YES];
cell.lblName.frame = CGRectMake(20 , 19, 250, 20);
if (venueObj.ivVenue)
[cell.ivVenue setImage:venueObj.ivVenue];
[cell.ivVenue setHidden:NO];
cell.lblName.frame = CGRectMake(80, cell.lblName.frame.origin.y, 200, cell.lblName.frame.size.height);
return cell;
【讨论】:
【参考方案2】:UITableViewCells
被重用,这就是 dequeueReusableCellWithIdentifier
: 方法所做的。为了节省内存,UITableView
仅实例化在任何给定点上尽可能多的单元格,然后继续重复使用它们。因此,您应该始终在重用之前清理单元格,即将其所有内容重置为nil
。
如果您使用的是自定义表格视图,例如 HomeCell
,则覆盖 -(void)prepareForReuse
并将图像设置为 nil。
【讨论】:
【参考方案3】:发生这种情况是因为您的单元格被重复使用,因此请编写以下代码:
HomeCell *cell = (HomeCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"HomeCell" owner:self options:nil];
for (id currentObject in topLevelObjects)
if ([currentObject isKindOfClass:[UITableViewCell class]])
cell = (HomeCell *) currentObject;
break;
【讨论】:
你的回答帮助我投票,但我解决的问题看我的回答【参考方案4】:你只需要在cellForRowAtIndexPath
中添加一行
NSString *CellIdentifier = [NSString stringWithFormat:@"S%1dR%1d",indexPath.section,indexPath.row];
然后改变
HomeCell *cell = (HomeCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
【讨论】:
这会有内存问题。你怎么看?它不会将任何单元格与另一个单元格重用,但在同一部分中具有相同的索引路径,从而导致创建的单元格数量与表格视图中存在的行数一样多。如果我错了,请纠正我。 是的,你写..在这段代码中,当用户滚动表格视图不重用旧单元格时,它会创建新单元格;) 有必要吗??我们可以通过重用单元格来创建相同的效果,从而减少内存使用量,然后这段代码将占用.. 但在某些情况下它是有帮助的。我知道cellForRowAtIndexPath
只调用可见单元格.. 它不调用不可见单元格...当用户滚动并显示单元格时,它不会创建新的(单元格)而是重用它:)
dequeueReusableCellWithIdentifier:CellIdentifier 仅当 cellIdentifier 相同时才有效。但在您的情况下,它对于每个单元格都是唯一的。只有遇到相同的 cellIdentifier 才会重用。即,如果用户滚动到最后,然后再次滚动到顶部。第一个单元将仅与先前创建的第一个单元一起重用。这是没有意义的。取一个像 25 个元素这样的大数组,然后检查创建了多少单元格。如果用户滚动到 tableview 的最后一个,它将正好是 25。【参考方案5】:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
HomeCell *cell = (HomeCell *) [tableView dequeueReusableCellWithIdentifier:@"HomeCell"];
if (cell == nil)
cell = [[HomeCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"HomeCell"] ;
VenueDC *venueObj = [subSubCategoriesArray objectAtIndex:indexPath.row];
cell.lblName.text = venueObj.name;
[cell.ivVenue setImage:nil];
if ([venueObj.imagesArray count] > 0)
[cell.ivVenue setImage:venueObj.ivVenue];
[cell.ivVenue setHidden:NO];
cell.lblName.frame = CGRectMake(80, cell.lblName.frame.origin.y, 200, cell.lblName.frame.size.height);
venueObj = nil;
return cell;
【讨论】:
现在它没有显示图像但是,你可以看到这个图像被隐藏了,所以它确实进入了“If”并将 lblName 向前移动 检查图像是否存在..如果没有则不要设置 lblname 的框架。希望有帮助【参考方案6】:您需要else
声明:
else
venueObj = nil;
【讨论】:
以上是关于重复的 UItableViewCell,UITableView 的行的主要内容,如果未能解决你的问题,请参考以下文章
如何在 UITableViewCell 上使用 CAGradientLayers
如何在 UITableViewCell 中添加多行文本字段?
当附件是UITableViewCellAccessoryCheckmark时,如何将文本置于UITableViewCell中