dequeueReusableCell 打破了cliptobounds

Posted

技术标签:

【中文标题】dequeueReusableCell 打破了cliptobounds【英文标题】:dequeueReusableCell breaks cliptobounds 【发布时间】:2016-11-18 19:30:38 【问题描述】:

我有一个非常简单的 UIScrollView,其中包含一些内容(许多子视图)。此滚动视图用于显示用户发布的一些帖子(图像 + 文本)。其中一个视图实际上是作者的图像,它溢出了底部单元格边界。因此,它与后面的单元格重叠,并且使用 clipToBounds = false 我能够获得所需的结果。如果我向下滚动,一切都会很好。当我开始向上滚动时,之前覆盖的视图现在被剪掉了。

Cell overlapping working fine Cell overlapping not working (when I scroll up)

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    let cellIdentifier = (indexPath.row % 2 == 0) ? "FeedCellLeft" : "FeedCellRight";
    let cell = feedScrollView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! FeedCell;
    self.setUpCell(cell, atIndexPath: indexPath);
    return cell

setUpCell 函数只是执行一些与 UI 相关的任务

let row = indexPath.row

    cell.postImage.downloadImageFrom(link: rows[row].image, contentMode: .scaleToFill)
    cell.postAuthorImage.downloadImageFrom(link: "https://pbs.twimg.com/profile_images/691867591154012160/oaq0n2zy.jpg", contentMode: .scaleToFill)
    cell.postAuthorImage.layer.cornerRadius = 22.0;
    cell.postAuthorImage.layer.borderColor = UIColor.white.cgColor
    cell.postAuthorImage.layer.borderWidth = 2.0;
    cell.postAuthorImage.layer.masksToBounds = true;

    cell.selectionStyle = .none

    cell.postData.layer.cornerRadius = 10.0;

    cell.contentView.superview?.clipsToBounds = false;
    cell.clipsToBounds = false;


    if (indexPath.row % 2 != 0) 
        cell.postData.transform = CGAffineTransform.init(rotationAngle: (4 * .pi) / 180);
     else 
        cell.postData.transform = CGAffineTransform.init(rotationAngle: (-4 * .pi) / 180);
    

似乎双端队列操作破坏了我所做的布局(使用自动布局)。我已经尝试了很多这样的解决方案

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) 
    cell.contentView.superview?.clipsToBounds = false;
    cell.clipsToBounds = false;
    cell.contentView.clipsToBounds = false;

但结果看起来总是一样的。每行的高度是固定的。

【问题讨论】:

【参考方案1】:

我认为问题在于子视图的层次结构。当您向下滚动时,您的单元格从上到下出列并以相同的顺序添加到UITableView,一切看起来都很好。因为前一个单元格在视图层次结构中位于以下单元格之上。 但是当你向上滚动时,单元格从下到上出列,这意味着顶部的单元格在前一个单元格的“后面”。您可以使用 Xcode 的 Debugging View Hierarchies 功能轻松检查它。

你可以试试bringSubviewToFront: 例如:

override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell,  forRowAt indexPath: IndexPath) 
    cell.superview.bringSubview(toFront cell)


更新版本

我在 Playgrounds 中进行了小型研究,发现只有一种合理的选择可以实现重叠单元,而不会出现巨大的性能问题。该解决方案基于cell.layer.zPosition 属性并且工作正常(至少在我的操场上)。我用以下代码更新了willDisplay cell: 中的代码:

override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) 
    cell.layer.zPosition = (CGFloat)(tableView.numberOfRows(inSection: 0) - indexPath.row)

根据.zPosition (Apple Developer Documentation) 的文档:

此属性的默认值为 0。更改此属性的值会更改屏幕上图层的从前到后的顺序。与具有较低值的层相比,较高的值会使该层在视觉上更靠近观察者。这会影响框架矩形重叠的图层的可见性。

所以我使用当前dataSource计数器作为minuend和当前单元格的indexPath.row作为subtrahend来计算每个单元格层的zPosition

您可以下载完整版我的游乐场here。

【讨论】:

嗨,这是一个很好的提示,它似乎有效,但反过来。现在它在我向上滚动时起作用,但在我向下滚动时不起作用,因为在最初布局单元格时也会调用 willDisplayCell G R E A T!有效!我欠你一杯啤酒!再次感谢! @DiegoViganò,如果我的回答对您有帮助,请将其标记为正确。

以上是关于dequeueReusableCell 打破了cliptobounds的主要内容,如果未能解决你的问题,请参考以下文章

如何在不弄乱内容的情况下标记 dequeueReusableCell?

使用出队的 dequeueReusableCell - 出队后单元格的 textField

DequeueReusableCell 仅在 iPhone 4S 上崩溃应用程序

dequeueReusableCell 之后的单元格布局

如何在具有 dequeueReusableCell 的同时以编程方式设置 tableview 样式以具有字幕?

iOS:UICollectionView 内容重置和 dequeueReusableCell