一个相当令人沮丧的困境,其中UICollectionViewCell使用UIImageView呈现,因为它是唯一的子视图。当加载图像的异步调用完成调用并调用setImage()方法时,将加载帧。因此,通常在设置图像之前,单元格已在视图中。
但是,当渲染单元格时图像被放入UIImageView时,图像不会应用contentMode属性,因此图像会以相当奇特的方式浮动并重叠相邻单元格,在滚动时会混乱。
当细胞重新使用时,即你从破碎的区域滚动然后再回到它,细胞再次显示正常。
细胞加载时看到的内容:
向外滚动然后回到视图中,细胞正常组织...细胞具有橙色背景颜色,因此在加载图像之前可以看到它们,所有细胞确实以所需的大小/位置呈现。这是溢出每个单元格的图像(即使clipToBounds为真)。
导致这种异常行为的原因是什么?图像从服务器加载异步,然后在本地缓存。如果我在集合上有.reloadData(),那么单元格也将自己“修复”。在第一次运行或加载后,它们看起来都是混合的。
显示单元重用方法和init方法的代码示例如下:
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()
}
}
答案 0 :(得分:0)
当涉及到自动布局时,我并不是非常有用,但我看起来内容视图具有基于图像视图的约束,该视图在该点没有大小或框架。设置图像时,图像视图框基于基于图像视图的内容视图。这可以解释为什么它只在第一次通过后才能正常工作。我不是100%它会解决问题,但是根据在init上传入的帧的宽度和高度,在init中为图像视图创建一个框架可能会有效。
setTranslatesAutoresizingMaskIntoConstraints
可能是主犯。
答案 1 :(得分:0)
我面临着完全相同的问题。解决方案来自另一个问题的answer。
只需使用界面生成器将集合视图的估计大小设置为无即可。