wake-ios/wake/Utils/GIFView.swift
2025-09-01 19:42:32 +08:00

125 lines
3.7 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import SwiftUI
import UIKit
struct GIFView: UIViewRepresentable {
let name: String
var onTap: (() -> Void)? = nil
func makeUIView(context: Context) -> UIImageView {
let imageView = UIImageView()
// GIF
guard let url = Bundle.main.url(forResource: name, withExtension: "gif"),
let data = try? Data(contentsOf: url),
let image = UIImage.gif(data: data) else {
return imageView
}
imageView.image = image
imageView.contentMode = .scaleAspectFit
//
if onTap != nil {
imageView.isUserInteractionEnabled = true
let tapGesture = UITapGestureRecognizer(target: context.coordinator, action: #selector(Coordinator.handleTap))
imageView.addGestureRecognizer(tapGesture)
}
return imageView
}
func updateUIView(_ uiView: UIImageView, context: Context) {}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: NSObject {
var parent: GIFView
init(_ parent: GIFView) {
self.parent = parent
}
@objc func handleTap() {
parent.onTap?()
}
}
}
// UIImageGIF
extension UIImage {
static func gif(data: Data) -> UIImage? {
guard let source = CGImageSourceCreateWithData(data as CFData, nil) else {
print("无法创建CGImageSource")
return nil
}
let count = CGImageSourceGetCount(source)
var images = [UIImage]()
var duration: TimeInterval = 0
for i in 0..<count {
guard let cgImage = CGImageSourceCreateImageAtIndex(source, i, nil) else {
continue
}
duration += UIImage.gifDelayForImageAtIndex(source: source, index: i)
images.append(UIImage(cgImage: cgImage, scale: UIScreen.main.scale, orientation: .up))
}
if count == 1 {
return images.first
} else {
return UIImage.animatedImage(with: images, duration: duration)
}
}
static func gifDelayForImageAtIndex(source: CGImageSource, index: Int) -> TimeInterval {
var delay = 0.1
let cfProperties = CGImageSourceCopyPropertiesAtIndex(source, index, nil)
let properties = cfProperties as? [String: Any] ?? [:]
let gifProperties = properties[kCGImagePropertyGIFDictionary as String] as? [String: Any] ?? [:]
if let delayTime = gifProperties[kCGImagePropertyGIFUnclampedDelayTime as String] as? Double {
delay = delayTime
} else if let delayTime = gifProperties[kCGImagePropertyGIFDelayTime as String] as? Double {
delay = delayTime
}
if delay < 0.011 {
delay = 0.1
}
return delay
}
}
// 使 -
struct GIFWithTapExample: View {
@State private var tapCount = 0
var body: some View {
VStack(spacing: 20) {
Text("点击GIF图片")
.font(.title)
GIFView(name: "Blind") {
//
Router.shared.navigate(to: .blindBox(mediaType: .video))
}
.frame(width: 300, height: 300)
.border(Color.blue) //
Text("点击次数: \(tapCount)")
.font(.subheadline)
}
}
}
struct GIFWithTapExample_Previews: PreviewProvider {
static var previews: some View {
GIFWithTapExample()
}
}