为啥将“viewWithTag”与“dequeueReusableCellWithIdentifier”一起使用?

Posted

技术标签:

【中文标题】为啥将“viewWithTag”与“dequeueReusableCellWithIdentifier”一起使用?【英文标题】:Why use "viewWithTag" with "dequeueReusableCellWithIdentifier"?为什么将“viewWithTag”与“dequeueReusableCellWithIdentifier”一起使用? 【发布时间】:2010-09-03 02:22:48 【问题描述】:

有人能解释一下为什么你应该使用viewWithTagdequeueReusableCellWithIdentifier 的单元格中获取子视图(例如UILabel 等)吗?

一些背景信息:我有一个自定义的UITableViewCell,里面有几个UILabels(我在下面复制了一个简单的版本)。这些标签在关联的 NIB 文件中定义,并使用 IBOutlets 声明并链接回自定义单元的控制器类。在tableview的dequeueReusableCellWithIdentifier中,我正在这样做:

CustomCell *customCell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:@"CustomCellId"];
if (customCell == nil) 
    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"customCell" owner:self options:nil];
    for (id oneObject in nib)
        if ([oneObject isKindOfClass:[CustomCell class]])
            customCell = (CustomCell *)oneObject;


customCell.firstLabel.text = @"Hello";
customCell.secondLabel.text = @"World!";

return customCell;

一切正常。但是,从我看到的教程来看,在更改标签的值时,我应该这样做:

UILabel *firstLabel = (UILabel *)[customCell.contentView viewWithTag:555];
firstLabel.text = @"Hello";

UILabel *secondLabel = (UILabel *)[customCell.contentView viewWithTag:556];
secondLabel.text = @"World!";

(标签的标签值已在NIB中设置)。

谁能告诉我首选哪种方法以及为什么?

谢谢!

【问题讨论】:

【参考方案1】:

viewWithTag: 只是一种快速而肮脏的方式来拉出子视图,而无需在父视图上设置 IBOutlet 属性,甚至不必创建 UITableViewCell 子类。

对于非常简单的情况,这是一个可以接受的解决方案,这就是viewWithTag: 的目的。但是,如果您要多次重用该单元格,或者您希望它具有对开发人员更友好的界面,那么您将需要像第一个示例中那样子类化并使用真实属性。

所以使用viewWithTag: 如果它是您在 IB 中设计的一个非常简单的单元格,没有子类并且只有几个标签。将具有真实属性的单元子类用于更重要的内容。

【讨论】:

【参考方案2】:

我已经意识到,如果元素以编程方式添加到单元格(即未在 NIB 中定义并通过 IBOutlets 连接),则使用“viewWithTag”检索元素很有用 - 这可以防止创建多个标签等对于单元格的每个实例。

【讨论】:

通常你应该使用 UITableViewCell 子类而不是快速而肮脏的 viewWithTag 方法。【参考方案3】:

对我来说,viewWithTag 是上帝赐予的。首先:像 taskinoor 所说的那样在循环中处理所有视图真的很容易。另外,我个人更喜欢这种方式,因为如果我查看代码并想看看视图发生了什么,我只需搜索标签。它在处理视图的任何地方都使用。与您必须查看代码和 xib 的 xib 方法相反。此外,如果您在 xib 中有屏幕外视图,您可能会监督它。 我发现很多其他程序员制作的 xibs 都充满了很多很多的观点。一些隐藏的,一些屏幕外的,无法分辨哪个是哪个,因为它们都是重叠的。 在这些情况下,我认为 xib 很糟糕。它们不再易于阅读。 我更喜欢用代码制作的一切。

但如果您决定使用标签,请记住避免对任何标签进行硬编码。而是制作一个#define 定义列表,以保持代码简洁易读。

【讨论】:

【参考方案4】:

我总是通过 IBOutlets 将子视图与我的 UITableViewCell 子类的属性挂钩,就像您所做的那样。我想不出任何使用 viewWithTag 的充分理由。

【讨论】:

【参考方案5】:

来自 UITableViewCell 类参考:“tableView:cellForRowAtIndexPath 中的表格视图委托:在重用单元格时应始终重置所有内容。”保持简单,清除内容视图。这对自定义单元类没有任何假设,没有强制转换,没有类检查:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
if (cell != nil)

    NSArray* contentSubViews = [cell.contentView subviews];
    for (UIView* viewToRemove in contentSubViews)
    
        [viewToRemove removeFromSuperview];
    

【讨论】:

【参考方案6】:

viewWithTag: 允许样式无需创建UITableViewCell 的自定义子类

您可以在 Interface Builder 中为原型 UITableViewCell 分配标签和重用标识符,然后在 UITableViewController 的实现中使用该标签出列并修改视图,而无需为该单元创建自定义类或创建 IBOutlets用于单元格的子视图。

在某些情况下,单元格的简单性让自定义类感觉有点矫枉过正。 viewWithTag: 允许您将自定义文本和图像添加到情节提要中的单元格,然后通过代码设置这些自定义项,而无需向您的 Xcode 项目添加额外的类文件。

【讨论】:

以上是关于为啥将“viewWithTag”与“dequeueReusableCellWithIdentifier”一起使用?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我不能使用 StoryBoard 从 viewWithTag 方法访问嵌套的 UIView?

为啥 dequeue() 占用这么多处理器时间?

OpenCV - 为啥光流不适用于 dequeue<Mat>?

viewWithTag 在子视图控制器中总是返回 nil

iphone sdk:无法重复使用viewWithTag的单元格(无法将setText重用于重复使用的标签)

XCode 6 UICollectionview viewwithtag 不起作用