UICollectionViewCell UIImageView 忽略 contentMode,溢出图像
UICollectionViewCell UIImageView ignores contentMode, overflows image
一个相当令人沮丧的困境,其中 UICollectionViewCell 使用 UIImageView 呈现,因为它只是子视图。当加载图像的异步调用完成调用并调用 setImage() 方法时,将加载框架。因此,通常在设置图像之前,单元格已经在视图中。
但是,当单元格被渲染时将图像放入 UIImageView 中时,图像不会应用 contentMode 属性,因此图像有效地浮动并以一种相当奇特的方式与相邻单元格重叠滚动时乱七八糟。
当单元格被重新使用时,即您从损坏的区域滚动离开然后返回到该单元格,单元格再次显示正常。
加载单元格时看到的内容:
滚动离开然后返回视图,单元格正常组织...单元格具有橙色背景颜色,因此可以在加载图像之前看到它们,所有单元格确实以所需的方式呈现 size/position。这是溢出每个单元格的图像(即使 clipToBounds 为 true)。
是什么导致了这种异常行为?图像从服务器异步加载,然后在本地缓存。如果我在集合上使用 .reloadData(),那么这些单元格也会 'fix' 自己。就在第一个 运行 之后或加载时,它们是否全部混杂在一起。
cell重用方法和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()
}
}
我在自动布局方面不是很有用,但我看起来内容视图有基于图像视图的限制,图像视图当时没有大小或框架。设置图像时,图像视图框架基于基于图像视图的内容视图。这可以解释为什么它只有在第一次通过后才能正常工作。我不是 100% 它会解决问题,但根据在 init 上传入的框架的宽度和高度在 init 中为图像视图创建一个框架可能会起作用。
setTranslatesAutoresizingMaskIntoConstraints
可能是罪魁祸首。
我遇到了完全相同的问题。解决方案来自另一个问题的answer。
只需使用界面生成器将集合视图的估计大小设置为 none。
一个相当令人沮丧的困境,其中 UICollectionViewCell 使用 UIImageView 呈现,因为它只是子视图。当加载图像的异步调用完成调用并调用 setImage() 方法时,将加载框架。因此,通常在设置图像之前,单元格已经在视图中。
但是,当单元格被渲染时将图像放入 UIImageView 中时,图像不会应用 contentMode 属性,因此图像有效地浮动并以一种相当奇特的方式与相邻单元格重叠滚动时乱七八糟。
当单元格被重新使用时,即您从损坏的区域滚动离开然后返回到该单元格,单元格再次显示正常。
加载单元格时看到的内容:
滚动离开然后返回视图,单元格正常组织...单元格具有橙色背景颜色,因此可以在加载图像之前看到它们,所有单元格确实以所需的方式呈现 size/position。这是溢出每个单元格的图像(即使 clipToBounds 为 true)。
是什么导致了这种异常行为?图像从服务器异步加载,然后在本地缓存。如果我在集合上使用 .reloadData(),那么这些单元格也会 'fix' 自己。就在第一个 运行 之后或加载时,它们是否全部混杂在一起。
cell重用方法和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()
}
}
我在自动布局方面不是很有用,但我看起来内容视图有基于图像视图的限制,图像视图当时没有大小或框架。设置图像时,图像视图框架基于基于图像视图的内容视图。这可以解释为什么它只有在第一次通过后才能正常工作。我不是 100% 它会解决问题,但根据在 init 上传入的框架的宽度和高度在 init 中为图像视图创建一个框架可能会起作用。
setTranslatesAutoresizingMaskIntoConstraints
可能是罪魁祸首。
我遇到了完全相同的问题。解决方案来自另一个问题的answer。
只需使用界面生成器将集合视图的估计大小设置为 none。