Files
e-party-iOS/yana/Views/ImagePreviewPager.swift
edwinQQQ 8362142c49 feat: 更新图片预览功能,支持本地与远程图片展示
- 在ImagePreviewPager中引入ImagePreviewSource枚举,支持本地和远程图片的统一处理。
- 优化OptimizedDynamicCardView,新增图片预览状态管理,集成全屏图片预览功能。
- 更新OptimizedImageGrid以支持图片点击事件,触发预览弹窗,提升用户体验。
2025-07-22 19:49:42 +08:00

87 lines
3.2 KiB
Swift

import SwiftUI
enum ImagePreviewSource: Identifiable, Equatable {
case local(UIImage)
case remote(String)
var id: String {
switch self {
case .local(let img):
return String(describing: img.hashValue)
case .remote(let url):
return url
}
}
static func == (lhs: ImagePreviewSource, rhs: ImagePreviewSource) -> Bool {
switch (lhs, rhs) {
case let (.local(l), .local(r)):
return l.pngData() == r.pngData()
case let (.remote(l), .remote(r)):
return l == r
default:
return false
}
}
}
struct ImagePreviewPager: View {
let images: [ImagePreviewSource]
@Binding var currentIndex: Int
let onClose: () -> Void
//
init(images: [UIImage], currentIndex: Binding<Int>, onClose: @escaping () -> Void) {
self.images = images.map { .local($0) }
self._currentIndex = currentIndex
self.onClose = onClose
}
//
init(images: [String], currentIndex: Binding<Int>, onClose: @escaping () -> Void) {
self.images = images.map { .remote($0) }
self._currentIndex = currentIndex
self.onClose = onClose
}
var body: some View {
ZStack(alignment: .topTrailing) {
Color.black.ignoresSafeArea()
TabView(selection: $currentIndex) {
ForEach(Array(images.enumerated()), id: \ .element.id) { idx, source in
Group {
switch source {
case .local(let img):
Image(uiImage: img)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color.black)
case .remote(let urlStr):
CachedAsyncImage(url: urlStr) { image in
image
.resizable()
.aspectRatio(contentMode: .fit)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color.black)
} placeholder: {
Rectangle()
.fill(Color.gray.opacity(0.3))
.overlay(
ProgressView()
.progressViewStyle(CircularProgressViewStyle(tint: .white.opacity(0.6)))
.scaleEffect(0.8)
)
}
}
}
.tag(idx)
}
}
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .always))
Button(action: { onClose() }) {
Image(systemName: "xmark.circle.fill")
.font(.system(size: 32))
.foregroundColor(.white)
.padding(24)
}
}
}
}