You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

Swift:如何让UIImageView平移X轴时保持水平翻转状态?

UIImageView平移动画中保持水平翻转状态的解决方法

问题原因分析

  1. Transform覆盖问题:你之前用CGAffineTransform(scaleX: -1, y: 1)设置翻转后,在动画块里直接设置translationX:100,这会完全替换掉之前的翻转transform——因为UIView的transform是单一属性,新的transform会覆盖旧的,导致翻转状态丢失。
  2. 图片翻转方法无效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

火山引擎 最新活动