【发布时间】:2020-02-25 21:52:30
【问题描述】:
问题
我正在使用UITableView 来显示信用卡的交易列表。如果交易是拒付,我将在标签中添加删除线样式:
当该特定单元被重复使用时,就会出现问题。即使重置标签的text 和attributedText 属性,删除线装饰仍然存在。
下面我添加了我的代码的相关部分:
表格视图
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)
}
}
我尝试过的
我尝试了一些方法,但没有成功:
- 覆盖
prepareForReuse并在此处重置标签的text和attributedText。 - 在
if transactionData.isChargeback之后创建else以设置不带装饰的transactionDescriptionLabel和transactionValueLabel属性文本
那么,当单元格被重复使用时,如何重置它的标签以删除我之前添加的删除线样式?
【问题讨论】:
-
为什么要在
TimelineTableViewCell中设置表格单元格内容,而不是在TimelineViewController中设置委托? -
@ekrenzin 更好地封装单元格内的 UI 元素。由于我已将它们声明为
private,因此可以从外部访问的唯一属性是transactionData。当我设置它时,它会更新单元格的 UI 元素。 -
我建议尝试修改委托中的单元格 UI,看看它是否有所作为。如果不起作用,那么您的模型可能有问题,没有考虑到新的但已经布置好的单元格。好问题:)
-
@ekrenzin 在尝试您的建议时,我偶然发现了解决方案:出于某种奇怪的原因,如果我只重置
attributedText,问题就不会再发生了。或者,如果我先重置attributedText,然后再重置text,问题也不会发生。根据文档,为任一属性分配新值会替换另一个属性的值,因此顺序无关紧要...也许这是UILabel错误???? -
我很高兴你和 Alex 一起找到了解决方案! :) 是的,这很奇怪......我过去遇到过类似的事情,这就是为什么我提到新的但已经布局的原因,我猜这里发生了类似的事情需要重置属性文本?表格单元格有时很奇怪哈哈~
标签: ios swift uitableview uikit uilabel