UITableView与HeaderCell的性能问题

时间:2018-09-09 13:22:10

标签: swift uitableview

当HeaderCell变得可见时,我遇到了性能问题,它占用了iPhone X上多达40%的CPU,并且出现了滞后。此UITableView显示静态数据(电视指南)。我每次向上和向下滚动时都看到滞后,“ tableView.dequeueReusableCell()”无济于事。如果我使用ExpandableHeaderView()创建HeaderCell以支持点击和扩展部分,则会遇到相同的问题。如果展开部分并在元素内部滚动,则看不到延迟。仅当HeaderCell出现在屏幕上时,才会出现性能问题。当用户打开View Controller时,他会看到每个通道的3个程序(当前和下两个),如果他点击节名称,他会看到该节(通道)的所有程序。 HeaderCell仅包含Label。我在Android应用程序上以相同的方式显示相同的数据,并且在简单的Android设备上可以正常工作。

func numberOfSections(in tableView: UITableView) -> Int {
        return Channels.count
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return Channels[section].Programs.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier)! as! TVGuideTableViewCell
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "HH:mm"
        let text = Channels[indexPath.section].Programs[indexPath.row].Name
        let dateString = dateFormatter.string(from:Channels[indexPath.section].Programs[indexPath.row].StartDate!)
        cell.label.text = text
        cell.timeLabel.text = dateString

        if (Channels[indexPath.section].Programs[indexPath.row].EndDate! < currentDate) {
            cell.label.textColor = UIColor.gray
        } else {
            cell.label.textColor = UIColor.white
        }

        if (Channels[indexPath.section].Programs[indexPath.row].StartDate! < currentDate) {
            cell.bell.isHidden = true
        } else {
            cell.bell.isHidden = false
        }

        if (Channels[indexPath.section].Programs[indexPath.row].EndDate! < currentDate) {
            Channels[indexPath.section].Programs[indexPath.row].expandedRow = false
        } else {
            if Channels[indexPath.section].expandedCount < 3 {
                Channels[indexPath.section].expandedCount += 1
                Channels[indexPath.section].Programs[indexPath.row].expandedRow = true
            }
        }

        return cell
    }

    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let headerCell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifierHeader) as! CustomHeaderTableViewCell
        headerCell.headerLabel.text = Channels[section].Name
        return headerCell
//        let header = ExpandableHeaderView()
//        header.customInit(title: Channels[section].Name, section: section, delegate: self as ExpandableHeaderViewDelegate)
//        return header
    }

    func toggleSection(header: ExpandableHeaderView, section: Int) {
        Channels[section].expanded = !Channels[section].expanded
        Channels[section].expandedCount = 0
        tableView.beginUpdates()
        for i in 0 ..< Channels[section].Programs.count {
            tableView.reloadRows(at: [IndexPath(row: i, section: section)], with: .automatic)
        }
        tableView.endUpdates()
    }

    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 38
    }

    func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
        return 2
    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        if(Channels[indexPath.section].expanded) {
            return 38
        } else {

            if (Channels[indexPath.section].Programs[indexPath.row].EndDate! < currentDate) {
                return 0
            } else {
                if Channels[indexPath.section].Programs[indexPath.row].expandedRow {
                    return 38.0
                } else {
                    return 0.0
                }
            }

        }
    }

class CustomHeaderTableViewCell: UITableViewCell {


    @IBOutlet weak var headerLabel: UILabel!

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

}

1 个答案:

答案 0 :(得分:1)

从您的代码中,我可以看到问题不是HeaderCell,问题是DateFormatter对象。因为每次您滚动并出现一个单元格时,都会创建一个新对象,并想象一下,如果一次有10-15个单元格,那么将重用/创建10-15个单元格,并在您滚动或重新加载Data时再次创建一个新对象。

因此,我的建议是在DateFormatter外部创建cellforRow对象,然后使用它通过调用来获取dateString

这只是一个假设,尝试一下,项目仍然出现请告诉我!