重用 UITableViewCell 时无法重置 UILabel 属性文本 [英] Can't reset UILabel attributedText when a UITableViewCell is reused

查看:34
本文介绍了重用 UITableViewCell 时无法重置 UILabel 属性文本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 UITableView 来显示信用卡的交易列表.如果交易是拒付,我将在标签中添加删除线样式:

I'm using a UITableView to show the list of transactions of a credit card. If the transaction is a chargeback, I'm adding a strikethrough style to the label:

重复使用该特定单元格时会出现问题.即使在重置标签的 textattributedText 属性之后,删除线装饰仍然存在.

The problem happens when that specific cell is reused. The strikethrought decoration is still there, even after resetting the text and attributedText property of the label.

下面我添加了我的代码的相关部分:

Below I've added the relevant parts of my code:

class TimelineViewController: UIViewController {

    private lazy var tableView: UITableView = {
        let tableView = UITableView.init(frame: view.frame, style: .plain)
        tableView.translatesAutoresizingMaskIntoConstraints = false
        tableView.register(TimelineTableViewCell.self, forCellReuseIdentifier: TimelineTableViewCell.reuseIdentifier)
        tableView.dataSource = self
        tableView.delegate = self
        return tableView
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        addTableViewOnView()
        getTimeline()
    }

}

extension TimelineViewController: UITableViewDataSource {

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: TimelineTableViewCell.reuseIdentifier,
                                                       for: indexPath) as? TimelineTableViewCell else { fatalError() }
        cell.transactionData = viewModel.timeline[indexPath.row]
        return cell
    }

}

表格视图单元格

class TimelineTableViewCell: UITableViewCell {

    static let reuseIdentifier = "TimelineTableViewCell"

    var transactionData: TimelineResponseModel! {
        didSet {
            // Reset the labels
            transactionDescriptionLabel.text = nil
            transactionDescriptionLabel.attributedText = nil
            transactionValueLabel.text = nil
            transactionValueLabel.attributedText = nil

            // Fill in the values
            transactionDescriptionLabel.text = transactionData.description
            transactionValueLabel.text = Formatter.currency.string(for: transactionData.balance)

            if transactionData.isChargeback {
                let value = Formatter.currency.string(for: transactionData.balance) ?? ""
                transactionDescriptionLabel.attributedText = transactionData.description.strikedThrough()
                transactionValueLabel.attributedText = value.strikedThrough()
            }
        }
    }

    private lazy var transactionDescriptionLabel: UILabel = {
        let transactionDescriptionLabel = UILabel()
        transactionDescriptionLabel.translatesAutoresizingMaskIntoConstraints = false
        transactionDescriptionLabel.font = UIFont.preferredFont(forTextStyle: .footnote)
        transactionDescriptionLabel.adjustsFontForContentSizeCategory = true
        transactionDescriptionLabel.textColor = UIColor.activeText()
        transactionDescriptionLabel.numberOfLines = 0
        return transactionDescriptionLabel
    }()

    private lazy var transactionValueLabel: UILabel = {
        let transactionValueLabel = UILabel()
        transactionValueLabel.translatesAutoresizingMaskIntoConstraints = false
        transactionValueLabel.font = UIFont.preferredFont(forTextStyle: .caption1).bold()
        transactionValueLabel.adjustsFontForContentSizeCategory = true
        transactionValueLabel.textColor = UIColor.activeText()
        return transactionValueLabel
    }()

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        addTransactionDescriptionLabel()
        addTransactionValueLabel()
    }

}

删除线样式

extension String {

    func strikedThrough() -> NSAttributedString {
        let strikethroughStyle = [NSAttributedString.Key.strikethroughStyle: NSUnderlineStyle.single.rawValue]
        return NSAttributedString(string: self, attributes: strikethroughStyle)
    }

}

我尝试过的

我尝试了一些方法,但没有成功:

What I've tried

I've tried some approaches, without success:

  • 覆盖 prepareForReuse 并在此处重置标签的 textattributedText.
  • if transactionData.isChargeback 之后创建一个 else 来设置 transactionDescriptionLabeltransactionValueLabel 属性文本装饰
  • Override prepareForReuse and reset the text and attributedText of the label there.
  • Create an else after the if transactionData.isChargeback to set the transactionDescriptionLabel and transactionValueLabel attributed text without the decoration

那么,当单元格被重复使用时,如何重置它的标签以删除我之前添加的删除线样式?

So, when the cell is reused, how can I reset it's labels to remove the strikethrough style I've added before?

推荐答案

你应该尝试在这里设置 .attributedText 而不是使用 `.text'.如果它不起作用,我会删除我的答案.

You should try to set with .attributedText here instead of using `.text'. If it won't work I'll delete my answer.

// Fill in the values
transactionDescriptionLabel.text = transactionData.description
transactionValueLabel.text = Formatter.currency.string(for: transactionData.balance)

所以,试试这个

transactionDescriptionLabel.attributedText = //
transactionValueLabel.attributedText = //

还有一件事.其实我不喜欢didSet.我建议您创建一种方法来配置您的单元格.这是我想告诉你的一个例子.

One more thing. Actually I don't like didSet. I suggest you to create a method to configure your cell. Here is an example of what I want to tell you.

func configure(with transactionData: TimelineResponseModel) {
   // Reset the labels
   transactionDescriptionLabel.text = nil
   transactionDescriptionLabel.attributedText = nil
   transactionValueLabel.text = nil
   transactionValueLabel.attributedText = nil

   // Fill in the values
   transactionDescriptionLabel.text = transactionData.description
   transactionValueLabel.text = Formatter.currency.string(for: transactionData.balance)

   if transactionData.isChargeback {
      let value = Formatter.currency.string(for: transactionData.balance) ?? ""
      transactionDescriptionLabel.attributedText = transactionData.description.strikedThrough()
      transactionValueLabel.attributedText = value.strikedThrough()
   }
}

下一步.

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    guard let cell = tableView.dequeueReusableCell(withIdentifier: TimelineTableViewCell.reuseIdentifier,
                                                   for: indexPath) as? TimelineTableViewCell else { fatalError() }
    // Thats what I really like
    cell.configure(with: viewModel.timeline[indexPath.row])
    return cell
}

这篇关于重用 UITableViewCell 时无法重置 UILabel 属性文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆