通过将代码移动到willDisplayHeaderView

时间:2016-09-07 03:04:11

标签: ios swift uitableview

我的桌面视图不能顺利滚动。我在苹果看到了这个评论。

  

但是非常重要的是仍然存在:tableView:cellForRowAtIndexPath:方法,它应该在UITableView的dataSource中实现,为每个单元调用并且应该快速工作。因此,您必须尽快返回重用的单元实例。

     

此时不要执行数据绑定,因为没有单元格   屏幕呢。为此您可以使用   tableView:willDisplayCell:forRowAtIndexPath:可以的方法   在UITableView的委托中实现。该方法完全称为   在UITableView的界限中显示单元格之前。

来自Perfect smooth scrolling

所以我试图将viewForHeaderInSection中的所有代码实现到willDisplayHeaderView(注意,我使用的是部分而不是行,因为我有自定义部分)。但是,我收到了一个“致命的错误:在展开可选值时意外发现nil”错误

let cell = tableView.headerViewForSection(section) as! TableSectionHeader

以下是我崩溃的原始代码和尝试代码

原创(注意,此代码可以正常使用我想要改进的一些小的滚动滞后问题)

func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    if let cell = tableView.dequeueReusableHeaderFooterViewWithIdentifier("TableSectionHeader") as? TableSectionHeader {

        // Cancel request of current cell if there is a request going on to prevent requesnt info from background from previous use of same cell
        cell.AlamoFireRequest?.cancel()

        var image: UIImage?
        if let url = post.imageUrl {
            image = DiscoverVC.imageCache.objectForKey(url) as? UIImage
        }

        cell.configureCell(post) // This is data binding part
        cell.delegate = self

        return cell

    } else {
        return TableSectionHeader()
    }
}

func tableView(tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {

}

尝试

func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    if let cell = tableView.dequeueReusableHeaderFooterViewWithIdentifier("TableSectionHeader") as? TableSectionHeader {
        return cell

    } else {
        return TableSectionHeader()
    }
}

func tableView(tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {

    let cell = tableView.headerViewForSection(section) as! TableSectionHeader

    // Cancel request of current cell if there is a request going on to prevent requesnt info from background from previous use of same cell
    cell.AlamoFireRequest?.cancel()

    var image: UIImage?
    if let url = post.imageUrl {
        image = DiscoverVC.imageCache.objectForKey(url) as? UIImage
    }

    cell.configureCell(post) // This is data binding part
    cell.delegate = self
}

-----更新以解决Michael的回答------

由于回复有字数限制,以下是对迈克尔答案的答复

你是对的,我已经更新了我在问题中获得摘录的地方。我的错误

我同意问题很可能在其他地方撒谎,但这是我目前正在经历的事情。我的桌面视图滚动好,但有时当有图像时,它会减慢一点。因此,我正在通过一些步骤来消除任何潜在原因。

我特意没有使用的原因,如果让这里是因为我期待显示单元格将是TableSectionHeader。我试着在那时添加它,我总是得到一个失败的演员。

我将UITableViewHeaderFooterView子类化的原因是因为我的headerview是一个Xib文件,其中我有func configureCell()所以我可以调用cell.configureCell。 (以及许多其他功能)

我的标题包含一些项目,例如

  1. 标签显示从firebase下载的标题,日期和时间
  2. 可以选择的图片
  3. 图片说明
  4. 喜欢btn,commentbtn,更多,btn
  5. 所有这些函数都在我的TableSectionHeader.swift中解决,它继承自UITableViewHeaderFooterView

    你能解释一下你的意思吗?“看起来很可疑你正试图在状态中存储状态 - 你应该在tableView之外存储状态。”?

    我在这里取消Alamofire请求的原因是因为该单元格已经出列。因此,如果用户滚动得非常快,则该单元将获得许多alamofire请求。所以我先取消它并重新打开下载请求(在cell.configureCell内),如果我的缓存中没有任何内容

    我不确定打印部分如何帮助识别。我认为我在这里把所有东西都放在了willDisplayHeaderView代码中(在大多数情况下你会把它放在viewForHeaderInSection中),这是一个遗憾的错误。或许它只是语法

2 个答案:

答案 0 :(得分:0)

您已经在方法中获得了标题视图,您只需要进行投射即可。试试这个:

func tableView(tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {

    guard let cell = view as? TableSectionHeader else { return }

    cell.AlamoFireRequest?.cancel()

    ...
}

答案 1 :(得分:0)

我不认为评论来自Apple,我认为您的问题可能在其他地方(例如,使用应在后台运行的任务来阻止主队列)。如果您发布TableSectionHeader的内容,这可能会变得更加清晰。

无论如何按下,您将在以下行中获得零值异常:

let cell = tableView.headerViewForSection(section) as! TableSectionHeader

这是因为你强迫演员阵容为TableSectionHeader,而且毫无疑问它不是一个。如果您将其更改为if letguard let,则会看到不同的代码路径。

因为你显然希望它总是属于那种类型(毕竟,这就是你在viewForHeaderInSection中创造的),所以你发现了一些你没有意识到的事情(为什么你呢?是否继承UITableViewHeaderFooterView?)。我倾向于在两个部分打印部分编号和视图,以便您知道实际发生了什么。它看起来很可疑,就像你试图在标题中存储状态一样 - 你应该将状态存储在tableView之外。

此外,应该不需要取消Alamofire请求,因为这不是性能问题的原因 - 检索图像应该只是触发另一个请求。否则,当用户滚动时,不会显示任何图像,因为请求将一直被取消。他们必须单独离开屏幕并等待这些图像加载,然后再滚动到其他地方。