Swift:如何让UIImageView平移X轴时保持水平翻转状态?
UIImageView平移动画中保持水平翻转状态的解决方法
问题原因分析
- Transform覆盖问题:你之前用
CGAffineTransform(scaleX: -1, y: 1)设置翻转后,在动画块里直接设置translationX:100,这会完全替换掉之前的翻转transform——因为UIView的transform是单一属性,新的transform会覆盖旧的,导致翻转状态丢失。 - 图片翻转方法无效:
withHorizontallyFlippedOrientation()只是修改UIImage的方向元数据,并没有实际翻转像素,UIImageView渲染时会根据方向自动调整,所以看起来和原图没区别。
解决方案一:组合Transform(推荐,无需修改图片)
动画时把翻转和平移的transform组合起来,而不是单独设置,这样就能同时保持翻转和位移状态:
func dragonMoveRight() { // 先创建翻转transform,再组合平移transform let flipTransform = CGAffineTransform(scaleX: -1, y: 1) let moveAndFlipTransform = flipTransform.translatedBy(x: 100, y: 0) // 启动原始动画序列(翻转由transform实现,无需修改图片) dragonImage.animationImages = dragon_anim dragonImage.startAnimating() UIView.animate(withDuration: 5.0) { self.dragonImage.transform = moveAndFlipTransform } completion: { _ in self.dragonMoveLeft() } } func dragonMoveLeft() { // 恢复到原始transform(无翻转,位移归位) let resetTransform = CGAffineTransform.identity // 恢复原始动画序列 dragonImage.animationImages = dragon_anim dragonImage.startAnimating() UIView.animate(withDuration: 5.0) { self.dragonImage.transform = resetTransform } completion: { _ in self.dragonMoveRight() } }
解决方案二:实际翻转图片像素
如果你需要直接使用翻转后的图片(比如某些特殊渲染场景),用Core Graphics手动绘制翻转后的图片,替代withHorizontallyFlippedOrientation():
func flipImages(images: [UIImage]) -> [UIImage] { var flippedImages: [UIImage] = [] for image in images { // 创建和原图尺寸、缩放一致的绘图上下文 UIGraphicsBeginImageContextWithOptions(image.size, false, image.scale) guard let context = UIGraphicsGetCurrentContext() else { flippedImages.append(image) continue } // 翻转画布后绘制图片,实现像素级水平翻转 context.translateBy(x: image.size.width, y: 0) context.scaleBy(x: -1.0, y: 1.0) image.draw(in: CGRect(origin: .zero, size: image.size)) // 获取翻转后的图片并结束上下文 if let flippedImage = UIGraphicsGetImageFromCurrentImageContext() { flippedImages.append(flippedImage) } else { flippedImages.append(image) } UIGraphicsEndImageContext() } return flippedImages }
使用这个方法后,你之前的动画逻辑可以保留,只要确保在向右移动时设置翻转后的图片数组,向左时恢复原数组即可。
内容的提问来源于stack exchange,提问作者Starrox




