You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在watchOS的SwiftUI中显示UIImageView.animationImages?

在watchOS SwiftUI中实现UIImageView.animationImages式的图片动画

由于watchOS中没有UIViewRepresentable,但可以借助WatchKit原生的WKInterfaceImage(它本身支持序列帧动画),通过WKInterfaceRepresentable将其包装为SwiftUI组件,替代原UIImageView.animationImages的功能。

实现步骤

  1. 创建WKInterfaceImage的SwiftUI包装器
import SwiftUI
import WatchKit

struct AnimatedImage: WKInterfaceRepresentable {
    let images: [UIImage]
    let duration: TimeInterval? // 动画总时长,可选,默认每张图间隔0.1秒
    
    func makeWKInterfaceObject(context: Context) -> WKInterfaceImage {
        WKInterfaceImage()
    }
    
    func updateWKInterfaceObject(_ imageView: WKInterfaceImage, context: Context) {
        if let duration = duration {
            // 指定总时长无限循环播放
            imageView.startAnimatingWithImages(
                in: NSRange(location: 0, length: images.count),
                duration: duration,
                repeatCount: 0
            )
        } else {
            // 使用默认时间间隔播放
            imageView.setImages(images)
            imageView.startAnimating()
        }
    }
    
    // 组件销毁时停止动画,避免资源浪费
    static func dismantleWKInterfaceObject(_ imageView: WKInterfaceImage, coordinator: ()) {
        imageView.stopAnimating()
    }
}
  1. 在SwiftUI列表行中使用
// 列表行视图
struct AnimatedListRow: View {
    let animationFrames: [UIImage]
    
    var body: some View {
        AnimatedImage(images: animationFrames, duration: 1.2)
            .frame(width: 60, height: 60)
    }
}

// 主列表视图
struct ContentView: View {
    // 模拟每行的动画图片数组
    let rowAnimations: [[UIImage]] = [
        (0...3).map { UIImage(named: "frame-\($0)")! },
        (0...5).map { UIImage(named: "anim-\($0)")! }
    ]
    
    var body: some View {
        List(rowAnimations, id: \.self) { frames in
            AnimatedListRow(animationFrames: frames)
        }
    }
}

额外扩展:动态控制动画启停

如果需要手动控制动画的播放/暂停,可以给包装器添加绑定属性:

struct AnimatedImage: WKInterfaceRepresentable {
    let images: [UIImage]
    let duration: TimeInterval?
    @Binding var isAnimating: Bool // 新增绑定属性
    
    func makeWKInterfaceObject(context: Context) -> WKInterfaceImage {
        WKInterfaceImage()
    }
    
    func updateWKInterfaceObject(_ imageView: WKInterfaceImage, context: Context) {
        imageView.setImages(images)
        if isAnimating {
            if let duration = duration {
                imageView.startAnimatingWithImages(in: NSRange(location: 0, length: images.count), duration: duration, repeatCount: 0)
            } else {
                imageView.startAnimating()
            }
        } else {
            imageView.stopAnimating()
        }
    }
    
    static func dismantleWKInterfaceObject(_ imageView: WKInterfaceImage, coordinator: ()) {
        imageView.stopAnimating()
    }
}

使用时传入绑定值即可:

AnimatedImage(images: animationFrames, duration: 1.2, isAnimating: $isPlaying)

内容的提问来源于stack exchange,提问作者Reinhard Männer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 01:10:33