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 上崩溃应用程序