同时旋转UIImageView及对应UIImage时二次旋转图片无变化的问题排查
问题分析与解决方案
嘿,我来帮你揪出这个旋转问题的根源!你遇到的第二次旋转没变化的情况,主要是两个关键错误导致的:
核心问题
旋转后的图片从未更新到UIImageView
你在后台线程生成了rotatedImage,但从来没有把它赋值回imageToRotate.image!这意味着你的UIImageView自始至终显示的都是原始图片,只是通过transform做了旋转变换。第二次点击时,transform累加旋转到180度,但图片本身还是原样,视觉上就会出现“没变化”的错觉。重复旋转的逻辑冲突
你同时对UIImageView的transform做动画,又旋转UIImage本身——这相当于对同一个视觉效果做了两次旋转。比如第一次点击后,transform转了90度,图片也转了90度,最终显示的是图片被转了180度,这和你预期的“旋转90度”完全不符,后续操作自然会混乱。
正确实现方案
根据你的需求(流畅动画+永久保存旋转后的图片),我给你两种针对性的解决方案:
方案一:永久修改图片+流畅动画
这个方案先通过transform做过渡动画,动画结束后再替换图片并重置transform,保证下次旋转基于最新的图片:
let imageToRotate = UIImageView() @objc func rotateImageButtonTapped() { let rotationAngle = CGFloat.pi / 2 // 1. 先执行流畅的UI旋转动画 UIView.animate(withDuration: 0.3, animations: { self.imageToRotate.transform = self.imageToRotate.transform.rotated(by: rotationAngle) }) { _ in // 2. 动画结束后,在后台处理图片旋转(避免卡顿) DispatchQueue.global(qos: .userInteractive).async { guard let originalImage = self.imageToRotate.image else { return } let rotatedImage = originalImage.rotate(radians: rotationAngle) // 3. 回到主线程更新UI(必须在主线程操作UI控件) DispatchQueue.main.async { self.imageToRotate.image = rotatedImage self.imageToRotate.transform = .identity // 重置transform,因为图片本身已经旋转了 } // 4. 保存旋转后的图片数据 self.page.isRotated = .rotated(rotatedImage: rotatedImage?.jpegData(compressionQuality: 1) ?? Data()) } } }
方案二:仅临时旋转动画(无需修改原图)
如果你不需要永久保存旋转后的图片,只需要临时的动画效果,那完全不用处理UIImage本身,只用transform动画就够了:
let imageToRotate = UIImageView() @objc func rotateImageButtonTapped() { UIView.animate(withDuration: 0.3) { self.imageToRotate.transform = self.imageToRotate.transform.rotated(by: CGFloat.pi / 2) } // 如果不需要保存,下面这行可以删掉 // self.page.isRotated = ... }
额外检查点
还要确认你的UIImage旋转扩展是否正确,错误的旋转逻辑也会导致图片看起来没变化。这里给你一个靠谱的扩展实现:
extension UIImage { func rotate(radians: CGFloat) -> UIImage? { // 计算旋转后的图片尺寸 let rotatedSize = CGRect(origin: .zero, size: self.size) .applying(CGAffineTransform(rotationAngle: radians)) .integral.size UIGraphicsBeginImageContext(rotatedSize) guard let context = UIGraphicsGetCurrentContext() else { return nil } // 平移到画布中心再旋转 context.translateBy(x: rotatedSize.width / 2, y: rotatedSize.height / 2) context.rotate(by: radians) // 绘制原始图片 self.draw(in: CGRect(x: -self.size.width/2, y: -self.size.height/2, width: self.size.width, height: self.size.height)) let rotatedImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return rotatedImage } }
内容的提问来源于stack exchange,提问作者esraaed
相关产品推荐
相关产品推荐

