Swift-使用tableView.dequeueReusableCell时数据无法正确显示

时间:2019-05-01 03:31:51

标签: ios swift uitableview

在应用程序中按下某些按钮时,它们的名称,按下的开始和结束时间会显示在UITableView中。

这在使用自定义UITableViewCell时很好用,但是在设置tableView.dequeueReusableCell之后,UITableView在要显示数据时将第一个单元格显示为空白单元格。如果添加了更多数据,则现在显示不可见的第一个输入,但是最后一个输入丢失/隐藏。

我发现了类似的问题,并实施了似乎是罪魁祸首的方法,但这对我没有用。

    timelineTableView.contentInsetAdjustmentBehavior = .never
    timelineScrollViewContainer.contentInsetAdjustmentBehavior = .never
    timelineTableView.contentOffset = .zero

我还试图更改横断面的高度,但也无济于事。

值得一提的是,数据在UITableView中无法正确显示,但仍在plist中正确保存。

UITableView是在ViewDidLoad期间加载的,正如在其他问题中提到的那样,这似乎是一些错误的问题。

双硫烯还有另一种解决方案?谢谢你的帮助

cellForRowAt方法

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    if tableView ==  timelineTableView {

       //let cell = TimelineCell(frame: CGRect(x: 0, y: 0, width: 100, height: 40), title: "test", startTime: "test", endTime: "test", rawStart: "") // Used previously before using dequeueReusableCell

        var cell: TimelineCell = tableView.dequeueReusableCell(withIdentifier: timelineCellId, for: indexPath) as! TimelineCell

        if let marker = markUpPlist.arrayObjects.filter({$0.UUIDpic == endClipSelectedMarkerUUID}).first {
            cell = TimelineCell(frame: CGRect(x: 0, y: 0, width: 100, height: 40), title: "test", startTime: "test", endTime: "test", rawStart: "")
            cell.backgroundColor = marker.colour
            cell.cellLabelTitle.text = marker.name
            cell.cellUUID.text = marker.UUIDpic

            if let timeline = chronData.rows.filter({$0.rowName == marker.name}).first {
                if let start = timeline.clips.last?.str {
                    cell.cellStartTime.text = chronTimeEdited(time: Double(start))
                    cell.cellStartRaw.text = String(start)
                }
                if let end = timeline.clips.last?.end {
                    cell.cellEndTime.text = chronTimeEdited(time: Double(end))
                }
            }
        }
        return cell
}

TimelineCell.swift

class TimelineCell : UITableViewCell {

var cellLabelTitle: UILabel!
var cellStartTime: UILabel!
var cellEndTime: UILabel!
var cellStartRaw: UILabel!
var cellUUID: UILabel!

init(frame: CGRect, title: String , startTime: String, endTime: String, rawStart: String) {
    super.init(style: UITableViewCell.CellStyle.default, reuseIdentifier: "timelineCellId")

    backgroundColor = UIColor(red: 29/255.0, green: 30/255.0, blue: 33/255.0, alpha: 1.0)

    cellLabelTitle = UILabel(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
    cellLabelTitle.translatesAutoresizingMaskIntoConstraints = false
    cellLabelTitle.textColor = UIColor.black

    addSubview(cellLabelTitle)

    cellLabelTitle.widthAnchor.constraint(equalToConstant: 80).isActive = true
    cellLabelTitle.heightAnchor.constraint(equalToConstant: 30).isActive = true
    cellLabelTitle.centerYAnchor.constraint(equalTo: self.centerYAnchor, constant: 0).isActive = true
    cellLabelTitle.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 10).isActive = true

    cellStartTime = UILabel(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
    cellStartTime.translatesAutoresizingMaskIntoConstraints = false
    cellStartTime.textColor = UIColor.black

    addSubview(cellStartTime)

    cellStartTime.widthAnchor.constraint(equalToConstant: 80).isActive = true
    cellStartTime.heightAnchor.constraint(equalToConstant: 30).isActive = true
    cellStartTime.centerYAnchor.constraint(equalTo: centerYAnchor, constant: 0).isActive = true
    cellStartTime.leftAnchor.constraint(equalTo: cellLabelTitle.rightAnchor, constant: 10).isActive = true

    cellEndTime = UILabel(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
    cellEndTime.translatesAutoresizingMaskIntoConstraints = false
    cellEndTime.textColor = UIColor.black

    addSubview(cellEndTime)

    cellEndTime.widthAnchor.constraint(equalToConstant: 80).isActive = true
    cellEndTime.heightAnchor.constraint(equalToConstant: 30).isActive = true
    cellEndTime.centerYAnchor.constraint(equalTo: centerYAnchor, constant: 0).isActive = true
    cellEndTime.leftAnchor.constraint(equalTo: cellStartTime.rightAnchor, constant: 10).isActive = true

    cellStartRaw = UILabel(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
    cellUUID = UILabel(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
    addSubview(cellStartRaw)
    addSubview(cellUUID)

}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

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

创建表格视图

    timelineTableView.frame = CGRect(x: 0, y: 0, width: sideView.frame.width, height: sideView.frame.size.height)
    timelineTableView.delegate = self
    timelineTableView.dataSource = self
    timelineTableView.register(TimelineCell.self, forCellReuseIdentifier: timelineCellId)
    timelineTableView.translatesAutoresizingMaskIntoConstraints = false
    timelineTableView.separatorStyle = .none
    timelineTableView.backgroundColor = Style.BackgroundColor
    timelineTableView.contentInsetAdjustmentBehavior = .never
    timelineScrollViewContainer.contentInsetAdjustmentBehavior = .never
    timelineScrollViewContainer.addSubview(timelineTableView)
    timelineTableView.contentOffset = .zero

因此,使用下面的代码行进行概括,可以正确显示数据,但不能正确地重用单元格。

 let cell = TimelineCell(frame: CGRect(x: 0, y: 0, width: 100, height: 40), title: "test", startTime: "test", endTime: "test", rawStart: "")

使用下面的代码首先显示一个空白单元格,数据显示不正确,但是单元格可以正确地重复使用。

var cell: TimelineCell = tableView.dequeueReusableCell(withIdentifier: timelineCellId, for: indexPath) as! TimelineCell

1 个答案:

答案 0 :(得分:0)

更改cellForRowAt如下所示。我正在猜测您的chronData结构与源表的关系,因此它主要使用原始逻辑。 您需要清空应该为空的字段,否则它们将在您滚动时保持状态。

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    var cell: TimelineCell = tableView.dequeueReusableCell(withIdentifier: timelineCellId, for: indexPath) as! TimelineCell

    let marker = markUpPListFiltered
    cell.backgroundColor = marker.colour
    cell.cellLabelTitle.text = marker.name
    cell.cellUUID.text = marker.UUIDpic
    if let timeline = chronData.rows.filter({$0.rowName == marker.name}).first {
       if let start = timeline.clips.last?.str {
           cell.cellStartTime.text = chronTimeEdited(time: Double(start))
           cell.cellStartRaw.text = String(start)
       }
       else
       {
           cell.cellStartTime.text = ""
           cell.cellStartRaw.text = ""
       }
       if let end = timeline.clips.last?.end {
           cell.cellEndTime.text = chronTimeEdited(time: Double(end))
       }          
       else
       {
           cell.cellEndTime.text = ""
       }
    }
    return cell
}

假设您的过滤后的排序数据有一个名为markupPListFiltered的数组。在viewDidLoad或其他地方进行准备。您尚未显示其他数据源方法,因此我假设您可以根据需要更改这些方法,例如

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
  return markupPListFiltered.count
}

TimelineCell需要删除数据。您应该考虑使用情节提要来设计单元格,并将小部件与插座链接起来(请参阅表视图上的数百篇教程中的任何一篇,我建议Ray Wenderlich是一个很好的入门源)。