【发布时间】:2020-05-24 23:02:00
【问题描述】:
一个相当令人沮丧的困境是 UICollectionViewCell 使用 UIImageView 呈现,因为它只是子视图。当加载图像的异步调用完成调用并调用 setImage() 方法时,将加载帧。所以通常在设置图像之前,单元格就已经在视图中了。
但是,当渲染单元格时将图像放置到 UIImageView 中时,图像不会应用 contentMode 属性,因此图像有效地浮动并以一种相当特殊的方式与相邻单元格重叠,这种方式在滚动时会四处乱窜。
当重新使用单元格时,即您滚动离开损坏的区域然后返回到其中,单元格再次显示正常。
当单元格加载时你会看到什么:
滚开然后回到视图中,单元格会正常组织自己...单元格具有橙色背景颜色,因此可以在加载图像之前看到它们,所有单元格确实以所需的大小/位置呈现。它是溢出每个单元格的图像(即使 clipToBounds 为 true)。
是什么导致了这种异常行为?图像从服务器异步加载,然后在本地缓存。如果我 .reloadData() 在集合上,那么单元格也会“修复”自己。在第一次运行之后或加载时,它们是否看起来都混在一起了。
显示单元重用方法和初始化方法的代码示例如下:
class ThumbnailCell: UICollectionViewCell {
var imageView: UIImageView!
override init(frame: CGRect) {
super.init(frame: frame)
imageView = UIImageView(frame: contentView.bounds)
imageView.image = nil
imageView.clipsToBounds = true
imageView.contentMode = .ScaleAspectFill
imageView.setTranslatesAutoresizingMaskIntoConstraints(false)
contentView.addSubview(imageView)
let viewsDictionary = ["imageView" : imageView]
contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:[imageView]", options: .allZeros, metrics: nil, views: viewsDictionary))
contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:[imageView]", options: .allZeros, metrics: nil, views: viewsDictionary))
}
func resetImage() {
self.imageView.contentMode = .ScaleAspectFill
self.imageView.frame = contentView.bounds
self.imageView.clipsToBounds = true
}
func setImage(image: UIImage) {
resetImage()
self.imageView.image = image
}
override func prepareForReuse() {
super.prepareForReuse()
self.imageView.image = nil
resetImage()
}
}
【问题讨论】:
-
这可能与您初始化图像视图时有关。你在哪里/什么时候做这个?此外,您将objective-c 作为标签,并且可能希望删除它,因为它很快。
-
谢谢@SkylerLauren - 我也认为这可能与出租顺序有关。当异步调用下载列表完成时,调用 reloadData() 并且这也强制集合正常重新渲染。但是一直这么称呼它似乎很奇怪?无论如何,我添加了一个完整的示例。这只是一个简单的应用程序,所以不知道为什么会这样。
-
在自动布局方面我不是很有用,但我看起来内容视图具有基于图像视图的约束,此时没有大小或框架。设置图像时,图像视图框架基于基于图像视图的内容视图。这可以解释为什么它只有在第一次通过后才能正常工作。不是 100% 会解决问题,但是根据在 init 中传入的框架的宽度和高度为 init 中的图像视图创建一个框架可能会起作用。
-
你应该把它写成答案。 AutoLayout 对我来说看起来不错,但如果我只是使用已经设置的边界,删除所有与 AutoLayout 相关的事情(特别是
setTranslatesAutoresizingMaskIntoConstraints),那么所有帧都会正常显示。它有效! -
很高兴我能提供帮助。我担心不断调用 reload 会导致你在路上出现问题。我发表了我的评论作为答案,希望它能帮助其他有类似问题的人。这不是我看到的第一个问题 setTranslatesAutoresizingMaskIntoConstraints 是主要问题。祝你的应用好运 =)
标签: ios swift uiimageview uicollectionviewcell