ios - dequeueReusableCell 打破 cliptobounds

标签 ios swift uiscrollview autolayout

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

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);
    }

deque 操作似乎破坏了我所做的布局(使用自动布局)。我试过很多这样的解决方案

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

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

最佳答案

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

你可以尝试 bringSubviewToFront: 例如:

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

Updated version

我在 Playgrounds 中做了一些小的研究,发现只有一个合理的选择可以实现重叠单元而不会出现巨大的性能问题。该解决方案基于 cell.layer.zPosition 属性并且工作正常(至少在我的 Playground 中)。我用以下代码更新了 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 ) 的文档:

The default value of this property is 0. Changing the value of this property changes the the front-to-back ordering of layers onscreen. Higher values place this layer visually closer to the viewer than layers with lower values. This can affect the visibility of layers whose frame rectangles overlap.

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

You can download full version of my playground here.

关于ios - dequeueReusableCell 打破 cliptobounds,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40684687/

相关文章:

ios - 如何使用 Swift 解析 PDF 页面中的内容

iPhone、Cocos2D - 触摸屏幕时左/右移动 Sprite

ios - 如何将sqlite文件导入ios中app的文档目录?

ios - 在 Swift 中采用 FIRGeoPoint 到 Codable 协议(protocol)

ios - 底部UITableView隐藏时如何让UIScrollView占据屏幕高度?

ios - 让 UIScrollView 与 AutoLayout 一起工作

iOS - Scrollview 的滚动条显示但不滚动内容

c# - 将不同的对象分配给 C# 中的一个对象

ios - Swift iOS - 使用 CATransform3D .m34 属性更改 Swift 中的视角时,对变换应用额外的更改

arrays - 展开可选值时发现 nil(音乐库)