在 Swift/Objective-C 中重用 tableviewcell 时,属性标签不会消失

Posted

技术标签:

【中文标题】在 Swift/Objective-C 中重用 tableviewcell 时,属性标签不会消失【英文标题】:Attributed label won't go away when tableviewcell is reused in Swift/Objective-C 【发布时间】:2020-10-06 17:42:45 【问题描述】:

对于表格视图,我从来没有遇到过重复使用单元格后文本标签持续存在的问题。

当您在数据源更改后重新加载 tableview 时,tableviewcells 会获取最新数据并相应地绘制自己。

但是,我现在遇到了属性标签的问题。从数据源中删除项目以便重新使用 tableviewcell 后,属性标签会保留在单元格中。不用说,剩余的属性标签与单元格中的内容无关。它只是附着在细胞上,不会消失。

问题描述here:

在上面的答案中,该人说他在使用常规文本标签执行任何操作之前将其设置为 nil,从而摆脱了属性标签。

transactionDescriptionLabel.attributedText = nil
transactionValueLabel.attributedText = nil
Or, if I reset the attributedText first, and then reset the text, it also works:

transactionDescriptionLabel.attributedText = nil
transactionValueLabel.attributedText = nil
transactionDescriptionLabel.text = nil
transactionValueLabel.text = nil 

将属性标签设置为 nil 似乎可以解决我的问题,但我以前从未需要将常规 textLabel 设置为 nil,并且我试图了解为什么我必须将属性标签设置为 nil。

当你有一个属性标签时,当你出列单元格时是否需要将它设置为nil?或者,除了将其设置为空字符串之外,当您不再在 tableview 中显示它时,让它消失的正确方法是什么?

提前感谢您的任何建议。

【问题讨论】:

我想说这是因为作者在.text.attributedText 上混合了NSAttributedString + NSString,并且label 属性很好地混合了它,保留了属性的旧值仅设置.text 时:避免混合它们。 程序点:您将 contents 设置为 nil,而不是将标签设置为 nil。将标签设置为 nil 将如下所示:transactionDescriptionLabel = nil(您可能不想这样做,因为您将失去对视图的访问权限,即使它仍然在视图层次结构中。) 我实际上有两个单独的标签,一个用于常规字符串,另一个用于属性字符串,我正在淡出一个带有 alpha 属性的标签。但是,在淡出属性字符串然后从 tableview 中删除项目后,属性字符串会在叠加在新标签上的单元格中停留...... 所以可以说AttributeLabel.text = nil;这样可以保留标签吗? 你可以在 Playgrounds 中测试它,使用:label.text = "First Value"; label.attributedText = label.text?.strikedThrough() //from linked question; label.text = "Hello there",每次都显示label 输出,你会看到的。 【参考方案1】:

我刚刚偶然发现了与NSUnderlineStyleAttributeName 完全相同的问题。仅当满足条件时,我才必须在 UITableViewCell 内的 UILabel 中加下划线。滚动单元格后,标签会不断重复使用属性。

我尝试了几种解决方法,将label.textlabel.attributedText 设置为nil,删除属性等...没有任何效果。

最后,我在NSAttributedString 文档中找到了实际的解决方案(RTFM,始终是答案):

为下划线和删除线属性定义了枚举:

NSUnderlineStyleNone = 0x00

UIKIT_EXTERN NSAttributedStringKey const NSStrikethroughStyleAttributeName API_AVAILABLE(macos(10.0), ios(6.0));  // NSNumber containing integer, default 0: no strikethrough
UIKIT_EXTERN NSAttributedStringKey const NSUnderlineStyleAttributeName API_AVAILABLE(macos(10.0), ios(6.0));      // NSNumber containing integer, default 0: no underline

总而言之,删除下划线或罢工属性的实际方法是将其设置为NSUnderlineStyleNone0

NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc] initWithString:text];
[attributeString setAttributes:@NSUnderlineStyleAttributeName:@(NSUnderlineStyleNone) range:(NSRange)0, [attributeString length]];
label.attributedText = attributeString;

【讨论】:

【参考方案2】:

label.attributedText 也将具有字符串的样式属性。

在重用之前,我的意思是在设置attributedText 属性甚至一次之前,样式属性将设置为默认值。如果您使用xib/storyboard,您可以在属性检查器中看到标签的默认样式,或者如果您已经编辑了这些值,那么您已经知道了。

现在,如果您设置label.text = "This is just text"。这采用提供的默认样式。

如果你必须在某个时候分配

    label.attributedText = NSAttributedString(string: "Attributed text", attributes: someAttributes)

所以从现在开始,如果你重复使用这个标签,并且只设置文本像label.text = "This is just text" 这会导致标签重用之前通过 someAttributes 提供的样式

因此,如果您重复使用单元格并且其中的标签在不同的行中具有不同的样式,则最好始终设置 attributedText 具有您所需属性的属性。 点赞 1

现在,如果您完全不需要该标签,您可以通过 label.removeFromSuperview() 将其从视图层次结构中删除(在这种情况下请谨慎处理重用,仅当您确定不会重用此视图时才使用它访问已删除的标签)

【讨论】:

以上是关于在 Swift/Objective-C 中重用 tableviewcell 时,属性标签不会消失的主要内容,如果未能解决你的问题,请参考以下文章

如何创建符合 Swift 和 Objective-C 之间共享协议的类方法?

在视图控制器上不显示视图控制器 - Swift / Objective-C

在 Swift/Objective-c 中按媒体类型自定义图像选择器

是否可以以编程方式从 Swift/Objective-C 中的 UIViewController 或 Storyboard 中获取基本 UIViewController 的标识符?

UIStoryBoardSegue 方法的 iOS Swift 问题

Moya中的参数编码