UICollectionViewCell UIImageView忽略contentMode,溢出图像

时间:2015-02-14 16:58:50

标签: ios swift uiimageview uicollectionviewcell

一个相当令人沮丧的困境,其中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()
    }
}

2 个答案:

答案 0 :(得分:0)

当涉及到自动布局时,我并不是非常有用,但我看起来内容视图具有基于图像视图的约束,该视图在该点没有大小或框架。设置图像时,图像视图框基于基于图像视图的内容视图。这可以解释为什么它只在第一次通过后才能正常工作。我不是100%它会解决问题,但是根据在init上传入的帧的宽度和高度,在init中为图像视图创建一个框架可能会有效。

setTranslatesAutoresizingMaskIntoConstraints

可能是主犯。

答案 1 :(得分:0)

我面临着完全相同的问题。解决方案来自另一个问题的answer

只需使用界面生成器将集合视图的估计大小设置为无即可。