使用 CGAffineTransform 旋转后更新 UIImageView 框架时出现奇怪的挤压

Posted

技术标签:

【中文标题】使用 CGAffineTransform 旋转后更新 UIImageView 框架时出现奇怪的挤压【英文标题】:Weird squishing when updating UIImageView frame after rotating with CGAffineTransform 【发布时间】:2017-08-20 01:55:39 【问题描述】:

我的主视图中有两个按钮和一个 UIImageView。一个按钮尝试将 UIImageView 旋转 30 度,另一个按钮将 UIImageView 的框架更新为自身。

我不希望将框架设置为自身会在视觉上影响任何东西,但如果图像处于默认方向以外的任何旋转状态,它似乎会“挤压”图像。我偶然发现了这一点,因为我想更新 UIImageView 的框架,以便在旋转后更改其 x 和 y 坐标。

因此,只要我从不按更新框架按钮,旋转按钮似乎就可以正常工作。但是,如果我在视图旋转时按下第二个按钮,它会将图像压缩到我不理解或不知道如何撤消的状态。

第二个按钮“挤压”图像的视频: https://streamable.com/ba7zd

第二个按钮的视频仅“挤压”而旋转不是默认方向:https://streamable.com/vo3cd

发生这种情况的原因是什么? This question 和 this question 似乎都捕捉到了类似的场景,但我不确定如何应用这两种解决方案。

在视图控制器中:

@IBOutlet weak var dog: UIImageView!

@IBAction func breakRotate(_ sender: UIButton) 
    self.dog.frame = self.dog.frame  // squishes if rotated


@IBAction func rotateDog(_ sender: UIButton) 
    UIView.animate(withDuration: 1.5, delay: 0, options: [.allowUserInteraction], animations: 
        self.dog!.transform = self.dog!.transform.rotated(by: CGFloat(0.523599))  // 30 degrees in radians
    )

图片:

【问题讨论】:

【参考方案1】:

应用旋转后frame属性返回的值不是旋转后的框架,它是包围视图的最小边界矩形,它的大小可以与实际框架不同。 (documentation 表示该框架将是未定义的,应该被忽略,但实际上它返回的是最小边界矩形

当您对视图应用变换时,不应更改框架,因为它会干扰变换。

如果你想在转换后改变位置,你应该改变视图的center属性:

dog.center = newCenterPoint

最后,至于为什么您会看到这种不寻常的效果,当您进行转换时,它会自动将框架调整为新的最小边界矩形,而不会弄乱图像的大小,但是当您应用新的更改框架时回到视图,它不会知道这是转换的结果,并会尝试调整您的图像大小,这就是为什么您的图像会像那样被挤压。

【讨论】:

以上是关于使用 CGAffineTransform 旋转后更新 UIImageView 框架时出现奇怪的挤压的主要内容,如果未能解决你的问题,请参考以下文章

iOS 混合变换旋转 CGAffineTransform 的使用

使用 CGAffineTransform 旋转后更新 UIImageView 框架时出现奇怪的挤压

旋转超级视图后计算 CGAffineTransform 矩阵

iOS 混合变换旋转 CGAffineTransform

iphone sdk CGAffineTransform 获取对象的旋转角度

UIButton (w/image) 在应用基于旋转的 CGAffineTransform 后对设备方向做出奇怪的反应