【问题标题】:Why UITableVIew Display Data Incorrectly After Scrolling为什么 UITableVIew 滚动后显示数据不正确
【发布时间】:2021-04-29 19:57:36
【问题描述】:

我的代码很简单。我有一个要在 UITableView 上显示的固定字符串列表,带有自定义 UITableViewCell,它上面只有一个 UILabel。

我的问题是虽然数据最初显示正确,但滚动后显示不正确。

这里有更多细节。 DataSource 是一个列表[(String, something_else)]

列表的内容是

[("aaaaaa", something),
("bbbbbb", something),
("cccccc", something),
   ...
("rrrrrr", something)]

屏幕足够大,可以显示“aaaa”到“mmmm”。当我向下滚动时,下一个可见行应该是“nnnn”,但它是“rrrr”,在“rrrr”之后是“aaaa”、“bbbb”、“cccc”,然后我向上滚动,它给了我“eeee” ,“cccc”,“rrrr”。每次重启模拟器都略有不同。

正如您在下面的代码中看到的,我每次将cell 出列并设置cell.note 时都添加了print(cell.note),但控制台中的打印消息表明单元格已设置为正确的注释。是的,它看起来是正确的。 "mmm" 之后是 n,o,p,q,r,然后我向上滚动,是 f,e,d,c,b,a,它看起来是正确的。

我不明白为什么,也不知道如何解决。谷歌搜索没有提供任何帮助,所以我想尝试在这里寻求帮助。感谢您阅读本文。

以下是我的代码。非常简单的dataSource和delegate实现

extension ViewController: UITableViewDelegate, UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        data.count;
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableview?.dequeueReusableCell(withIdentifier: "NoteNodeCell") as! NoteNodeCell
        cell.note = data[indexPath.row].0        
        return cell
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 64
    }
}

NoteNodeCell 是一个自定义的 UITableViewCell。我基本上只是在里面加了一个UILabel。

class NoteNodeCell: UITableViewCell {
    var note: String {
        get { cellView.note }
        set { cellView.note = newValue }}
    
    var cellView:CellView = CellView()
    
    override func awakeFromNib() {
        super.awakeFromNib()
        
        if cellView.superview != contentView {
            contentView.addSubview(cellView)
        }
        
        cellView.translatesAutoresizingMaskIntoConstraints = false
        cellView.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
        cellView.leftAnchor.constraint(equalTo: contentView.leftAnchor).isActive = true
        cellView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
        cellView.rightAnchor.constraint(equalTo: contentView.rightAnchor).isActive = true
        
    }
    
    override func prepareForReuse() {
        super.prepareForReuse()
        note = ""
    }
}


class CellView: UIView {
    var note = "" { didSet { print(note) }}
    
    override func draw(_ rect: CGRect) {
        super.draw(rect)
        UIColor.white.setFill()
        UIRectFill(rect)
        let label = UILabel(frame: bounds)
        label.text = "  " + note
        label.font = UIFont(name: "Courier", size: 18)
        label.textColor = .white
        label.backgroundColor = .gray
        label.layer.cornerRadius = 5
        label.layer.masksToBounds = true
        UIColor.clear.setFill()
        addSubview(label)

    }
}

再次感谢您阅读本文。

【问题讨论】:

    标签: ios swift uitableview datasource


    【解决方案1】:

    在您的 CellView 课程中试试这个

    class CellView: UIView {
    let label = UILabel()
    var note = "" { 
        didSet { 
            print(note) 
            self.label.text = "  " + note // this
        }
    }
    
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupSubviews()
    }
    
    private func setupSubviews() {
        label.text = "  " + note
        label.font = UIFont(name: "Courier", size: 18)
        label.textColor = .white
        label.backgroundColor = .gray
        label.layer.cornerRadius = 5
        label.layer.masksToBounds = true
        addSubview(label)
    }
    

    }

    你的 UITableViewCell 需要这个

    let cellView = CellView(frame: .zero)
    

    如果这不起作用,请告诉我

    【讨论】:

    • 但是我有一个后续问题。我想如果我添加cell.setNeedsDisplay,它也可以解决问题,但它没有工作。你的解决方案奏效了。这意味着我不明白出了什么问题。你能帮忙解释一下吗?
    • @Goatt setNeedsDisplay() 通知系统您的视图需要重绘。假设您在调用 setNeedsDisplay 之前正确更新了 note 变量,我不明白为什么它不起作用。不过,我还没有看到您正在执行此操作的代码,因此我很难说更多。我认为在这样的绘图函数中无缘无故地重复重新声明和定义新标签是不好的做法。您无需重做所有操作即可更改标签的文本。这就是为什么我按照我的方式写我的。我很高兴它有帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多