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

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

问题描述

我正在使用 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:

当该特定单元格被重用时,就会发生问题.即使在重置标签的 text attributedText 属性之后,删除线装饰仍然存在.

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 并在此处重置标签的 text attributedText .
  • if transactionData.isChargeback 之后创建 else ,以设置 transactionDescriptionLabel transactionValueLabel 属性文本,而无需装饰
  • 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 attributedText的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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