如何在watchOS的SwiftUI中显示UIImageView.animationImages?
在watchOS SwiftUI中实现
UIImageView.animationImages式的图片动画 由于watchOS中没有UIViewRepresentable,但可以借助WatchKit原生的WKInterfaceImage(它本身支持序列帧动画),通过WKInterfaceRepresentable将其包装为SwiftUI组件,替代原UIImageView.animationImages的功能。
实现步骤
- 创建
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() } }
- 在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
相关产品推荐
相关产品推荐

