feat: 动效使用gif
This commit is contained in:
parent
5b83ace879
commit
023a64b947
BIN
wake/Assets/Images/Blind.gif
Normal file
BIN
wake/Assets/Images/Blind.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.5 MiB |
125
wake/Utils/GIFView.swift
Normal file
125
wake/Utils/GIFView.swift
Normal file
@ -0,0 +1,125 @@
|
||||
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?()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// UIImage的扩展,用于处理GIF
|
||||
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()
|
||||
}
|
||||
}
|
||||
@ -136,29 +136,64 @@ struct MediaUploadView: View {
|
||||
selectedMedia: Binding(
|
||||
get: { mediaPickerSelection },
|
||||
set: { newSelections in
|
||||
print("🔄 开始处理用户选择的媒体文件")
|
||||
print("📌 新选择的媒体数量: \(newSelections.count)")
|
||||
|
||||
// 记录当前已选择的媒体ID
|
||||
let existingMediaIDs = uploadManager.selectedMedia.map { $0.id }
|
||||
print("📋 当前已选择的媒体ID: \(existingMediaIDs)")
|
||||
|
||||
// 只处理尚未选择的媒体项
|
||||
let newItems = newSelections.filter { newItem in
|
||||
!uploadManager.selectedMedia.contains { $0.id == newItem.id }
|
||||
let isNew = !uploadManager.selectedMedia.contains { $0.id == newItem.id }
|
||||
print("🔍 检查媒体项 \(newItem.id) - \(isNew ? "新添加" : "已存在")")
|
||||
return isNew
|
||||
}
|
||||
|
||||
print("✅ 过滤后的新添加媒体数量: \(newItems.count)")
|
||||
|
||||
if !newItems.isEmpty {
|
||||
print("🔄 开始处理 \(newItems.count) 个新添加的媒体项...")
|
||||
|
||||
// 记录新添加的媒体类型
|
||||
newItems.forEach { item in
|
||||
switch item {
|
||||
case .image(let uiImage):
|
||||
print("🖼️ 添加图片 - 尺寸: \(uiImage.size.width)x\(uiImage.size.height)")
|
||||
case .video(let url, _):
|
||||
print("🎥 添加视频 - URL: \(url.lastPathComponent)")
|
||||
}
|
||||
}
|
||||
|
||||
// 将新项添加到现有选择的开头
|
||||
let newMedia = newItems + uploadManager.selectedMedia
|
||||
print("📊 更新媒体列表 - 总数: \(newMedia.count) (新增: \(newItems.count), 原有: \(uploadManager.selectedMedia.count))")
|
||||
|
||||
uploadManager.clearAllMedia()
|
||||
print("🧹 已清空现有媒体列表")
|
||||
|
||||
uploadManager.addMedia(newMedia)
|
||||
print("✅ 已添加新媒体到上传管理器")
|
||||
|
||||
// 如果没有选中的媒体,则选中第一个新增的
|
||||
if selectedIndices.isEmpty {
|
||||
selectedIndices = [0] // 选择第一个新增项的索引
|
||||
selectedIndices = [0]
|
||||
selectedMedia = newItems.first
|
||||
print("👆 自动选择第一个新增的媒体项: \(selectedMedia?.id ?? "nil")")
|
||||
} else {
|
||||
print("ℹ️ 保持当前选中的媒体项")
|
||||
}
|
||||
|
||||
// 开始上传新添加的媒体
|
||||
print("🚀 开始上传新添加的媒体...")
|
||||
uploadManager.startUpload()
|
||||
} else {
|
||||
print("ℹ️ 没有新的媒体项需要添加")
|
||||
}
|
||||
|
||||
// 重置选择
|
||||
mediaPickerSelection = []
|
||||
print("🔄 已重置媒体选择器状态")
|
||||
}
|
||||
),
|
||||
imageSelectionLimit: max(0, 20 - uploadManager.selectedMedia.filter {
|
||||
|
||||
@ -48,7 +48,7 @@ struct WakeApp: App {
|
||||
// 已登录:显示userInfo页面
|
||||
// ContentView()
|
||||
// .environmentObject(authState)
|
||||
UserInfo()
|
||||
MediaUploadView()
|
||||
.environmentObject(authState)
|
||||
} else {
|
||||
// 未登录:显示登录界面
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user