【问题标题】:UICollectionViewCell UIImageView ignores contentMode, overflows imageUICollectionViewCell UIImageView 忽略 contentMode,溢出图像
【发布时间】: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


【解决方案1】:

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

setTranslatesAutoresizingMaskIntoConstraints

可能是主要罪犯。

【讨论】:

  • 这绝对不是我的解决方案。我将图像视图的背景涂成红色,以便检查它的大小和大小是否正确,但是图像没有拉伸以填充可用空间。
  • @Ash 如果 UIImageView 的大小正确,您是否设置 imageView.contentMode = .ScaleAspectFill?如果 ImageView 的大小正确,这是我无法填充的唯一原因。
  • 我的问题原来与集合视图完全无关;图片解析不正确。
【解决方案2】:

我遇到了完全相同的问题。解决方案来自另一个问题的answer

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-26
    • 1970-01-01
    相关资源
    最近更新 更多