AnimationImageView.swift 1.99 KB
//
//  AnimationImageView.swift
//  hippo-watch Watch App
//
//  Created by shihao on 2025/7/7.
//

import SwiftUI
import Foundation
import UIKit
import ImageIO

struct AnimatedGIFView: View {
    let gifName: String
    @State private var currentFrame = 0
    @State private var frames: [UIImage] = []
    @State private var timer: Timer?
    
    var body: some View {
        Group {
            if !frames.isEmpty {
                Image(uiImage: frames[currentFrame])
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .frame(maxWidth: .infinity, maxHeight: .infinity)
            } else {
                Text("Loading...")
            }
        }
        .onChange(of: gifName) { _, _ in
            stopAnimation()
            loadFrames()
        }
        .onAppear {
            loadFrames()
        }
        .onDisappear {
            stopAnimation()
        }
    }
    
    private func loadFrames() {
        guard let gifPath = Bundle.main.path(forResource: gifName, ofType: "gif"),
              let gifData = NSData(contentsOfFile: gifPath),
              let source = CGImageSourceCreateWithData(gifData, nil) else { return }
        
        let frameCount = CGImageSourceGetCount(source)
        var loadedFrames: [UIImage] = []
        
        for i in 0..<frameCount {
            if let cgImage = CGImageSourceCreateImageAtIndex(source, i, nil) {
                let image = UIImage(cgImage: cgImage)
                loadedFrames.append(image)
            }
        }
        
        frames = loadedFrames
        if !frames.isEmpty {
            startAnimation()
        }
    }
    
    private func startAnimation() {
        timer?.invalidate()
        timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { _ in
            if !frames.isEmpty {
                currentFrame = (currentFrame + 1) % frames.count
            }
        }
    }
    
    private func stopAnimation() {
        timer?.invalidate()
        timer = nil
    }
}