在 UITableViewCell 中使 UIView 出队
Posted
技术标签:
【中文标题】在 UITableViewCell 中使 UIView 出队【英文标题】:Dequeueing UIViews withing UITableViewCell 【发布时间】:2012-05-01 06:52:01 【问题描述】:在使用 UITableView 的正常情况下,我有重用旧单元格的标准代码:
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath
static NSString *cellIdentifier = @"Cell";
UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
return cell;
然而,我注意到,当我将子视图添加到单元格时,它们并没有被删除,并且每次都会添加一个新视图。我在下面有一个例子可以完美地展示它:
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath
static NSString *cellIdentifier = @"Cell";
UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
UILabel *label = [[UILabel alloc] init];
label.text = @"HELLO";
label.frame = CGRectMake(arc4random() % 50, -1, 286, 45);
label.backgroundColor = [UIColor clearColor];
// Add views
[cell addSubview:label];
return cell;
我需要一些代码来再次重用我的标签,就像重用单元格一样。我该怎么办?
谢谢
【问题讨论】:
添加到单元格后只需释放标签即可。 删除标签或注释 if(cell==nil) 条件行。因此它会分配每个新单元格。它将彻底解决您的问题,但对大表有内存管理问题。 【参考方案1】:只有在创建新单元格时才必须添加子视图。如果您正在出队,则子视图已经存在,不应重新创建。
你的方法应该是:
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath
static NSString *cellIdentifier = @"Cell";
UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:cellIdentifier];
UILabel *label;
if (cell == nil)
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
label = [[UILabel alloc] init];
label.tag = 1;
// Add views
[cell addSubview:label];
else
// Label will already exist, get a pointer to it
label = [cell viewWithTag:1];
// Now set properties on the subview that are unique to each cell
label.text = @"HELLO";
label.frame = CGRectMake(arc4random() % 50, -1, 286, 45);
label.backgroundColor = [UIColor clearColor];
return cell;
请注意标签是如何仅在单元格为 nil 时创建的。否则,使用标签找到它。
【讨论】:
谢谢,真的很有帮助。这就是我认为我需要处理它但不知道如何编写它的方式。【参考方案2】:我需要一些代码以与单元格相同的方式再次重用我的标签 正在被重复使用。
不,您需要更好地了解表格视图设计。为什么视图被多次添加应该很明显——重用一个单元意味着你使用一个不再需要的 UITableViewCell
的先前实例(从而节省了新对象的昂贵分配)并将这个实例重用于新单元.但是这个前面的实例已经附加了标签,所以标签的数量增加了。
我将子类化UITableViewCell
并将标签创建放在这个新类的初始化代码中。 (或者创建一个UIView
子类并将其设置为单元格的contentView
,正如nice table tutorial by Matt Gallagher 中所建议的那样。)这是封装视图详细信息并将其隐藏在表数据源中的正确方法。
【讨论】:
【参考方案3】:您可以在 else
部分中使用类似 if(cell == nil)
for (UIView *sub in [cell.contentView subviews])
if([UILabel class] == [sub class])
NSLog(@"%@",[sub class]);
UILabel *label = (UILabel *)sub;
//do label coding ie set text etc.
【讨论】:
【参考方案4】:我在我的自定义表格单元类中使用延迟初始化视图。 它只需要加载视图和“addSubview”一次。
- (void) lazyInitTitleLabel
if (_titleLabel != nil)
return;
_titleLabel = [[UILabel alloc] initWithFrame: CGRectMake(10.0f, 10.0f, 200.0f, 30.0f)];
// Cell adds the label as a subview...
[self addSubview: _titleLabel];
您唯一需要注意的是重置视图显示的任何内容,例如标签中的文本和图像视图中的图像。如果您不这样做,旧内容可能会与回收的表格单元格一起重复使用。
祝你好运!
【讨论】:
以上是关于在 UITableViewCell 中使 UIView 出队的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Objective-C 的 UITableView 中使 UITableViewRowAction 完全透明
iOS - subivew 不能在 UITableViewCell 中居中