设置图像属性时,UIImageView 图像不会明显更新

Posted

技术标签:

【中文标题】设置图像属性时,UIImageView 图像不会明显更新【英文标题】:UIImageView image does not update visibly when image property is set 【发布时间】:2018-06-10 18:52:24 【问题描述】:

我有一个 UIImageView,它的用户交互是真实的,并且我已经给了一个点击手势识别器,它的动作处理程序如下:

@IBAction func tap(_ sender:UITapGestureRecognizer) 
    let iv = sender.view as! UIImageView
    let im = iv.image!
    let im2 = UIGraphicsImageRenderer(size:im.size).image  _ in
        UIColor.red.setFill()
        UIBezierPath(rect: CGRect(origin:.zero, size:im.size)).fill()
    
    iv.image = im2

我希望当我点击图像视图时显示的图像会被纯红色图像替换。这在我运行 Xcode 9.4 的 High Sierra 机器上运行良好。但在我运行 Xcode 9.2 的 Sierra MacBook 上,没有明显的反应。

这很奇怪。通过在调试器中暂停,我可以看到新图像正在正确构建:

图像正在被替换,但图像视图没有被重绘。添加像setNeedsDisplay 这样的调用没有任何作用。

此外,如果我继续将图像视图的图像替换为 不同 图像,我会看到 红色 图像!

    iv.image = im2
    delay(0.5) 
        iv.image = im // causes im2 to appear!
    

某种幕后缓存显然会导致图像视图在其显示中落后一个图像。

有人能解释一下吗?这可能是 ios 本身的一个错误,特别是在 9.2 中;如何解决它? (显然,我们可以批量替换另一个图像视图,但这并不能告诉我们缓存发生了什么。)

【问题讨论】:

我想代码从 UIViewController 运行。您不能只添加一个属性并从点击处理程序中直接使用它引用 imageView 吗?我的意思是我不会使用 sender.view 来引用 ImageView。 这可能有点牵强,但UIGraphicsImageRenderer 可能有一些“魔力”。如果您使用旧的UIGraphicsBeginImageContextWithOptionsUIGraphicsGetImageFromCurrentImageContext 等其他技术创建红色图像,您是否仍然存在此问题? @rmaddy 我根本不知道这是一个延伸;我也有同样的想法。我试试看…… @rmaddy 不,它不会改变任何东西。我认为“魔力”必须在图像视图本身(可能与图像是实时生成的事实相结合,但是我们如何解释生成的图像在调试器中可见的事实呢?)。 @lookaji 不,更改图像视图的引用方式不会改变任何事情。 【参考方案1】:

这似乎是一种解决方法:

iv.image = im2
delay(0.05) 
    iv.image = nil
    iv.image = im2

但是太可怕了...省略任何这些分配,或将 delay 减少为零(例如,通过调用 DispatchQueue.main.async 代替),会导致解决方法失败。

【讨论】:

此外,我还没有解释任何事情,尽管我现在有“有效”的代码。【参考方案2】:

在Xcode 13中遇到这个问题。在xib文件中设置contentModelcenter

iv.contentMode = .center

【讨论】:

正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center。

以上是关于设置图像属性时,UIImageView 图像不会明显更新的主要内容,如果未能解决你的问题,请参考以下文章

如何在构建 UIImageView 时创建图像

自动调整 UIImageView 的大小以适合底层图像

如何使UIImageView适合缩放图像

如何以编程方式在 Swift 中将 uiimageview 设置为 xcode 内置的 applewatch 图标图像?

UIImageView 在我设置图像时移动或调整大小

UIImageView 未在自定义 UITableViewCell 中显示图像