fix image view

This commit is contained in:
anlicheng 2025-04-14 11:16:52 +08:00
parent 91718319f8
commit 4fb871ddb9
3 changed files with 112 additions and 44 deletions

View File

@ -37,6 +37,18 @@ final class CacheManager {
} }
} }
//
func preloadImage(url: String) async {
guard !self.fileExists(urlString: url) else {
return
}
if let filename = self.getCacheFileName(urlString: url),
let data = try? await self.downloadImage(from: url) {
try? self.saveCacheFile(filename: filename, data: data)
}
}
// //
func fileExists(urlString: String) -> Bool { func fileExists(urlString: String) -> Bool {
guard let cacheFileName = getCacheFileName(urlString: urlString) else { guard let cacheFileName = getCacheFileName(urlString: urlString) else {

View File

@ -0,0 +1,73 @@
//
// FlexImage.swift
// dimensionhub
//
// Created by on 2025/4/14.
//
import SwiftUI
struct FlexImage: View {
let urlString: String
let width: CGFloat
let height: CGFloat
let placeholder: String
let mode: ImageMode
//
enum ImageMode {
case remote(String)
case local(Data)
}
init(urlString: String, width: CGFloat, height: CGFloat, placeholder: String) {
self.urlString = urlString
self.width = width
self.height = height
self.placeholder = placeholder
let cacheManager = CacheManager.shared
if let data = cacheManager.readFileContents(urlString: urlString) {
self.mode = .local(data)
} else {
Task.detached {
await cacheManager.preloadImage(url: urlString)
}
self.mode = .remote(urlString)
}
}
var body: some View {
switch self.mode {
case .remote(let url):
AsyncImage(url: URL(string: url)) { phase in
switch phase {
case .empty:
ProgressView()
case .success(let image):
image
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: width, height: height)
.clipped()
default:
Image(placeholder)
.resizable()
.aspectRatio(contentMode: .fill)
.clipped()
}
}
case .local(let data):
Image(uiImage: UIImage(data: data)!)
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: width, height: height)
.clipped()
}
}
}
#Preview {
//FlexImage()
}

View File

@ -189,52 +189,35 @@ extension IndexMainView {
Button(action: { Button(action: {
appNav.append(dest: .detail(id: item.id)) appNav.append(dest: .detail(id: item.id))
}) { }) {
AsyncImage(url: URL(string: item.thumb)) { phase in FlexImage(urlString: item.thumb, width: 370, height: 180, placeholder: "ph_img_big")
switch phase { .frame(width: 370, height: 180)
case .empty: .overlay(alignment: .topLeading) {
ProgressView() VStack(alignment: .leading, spacing: 8) {
case .success(let image): Text(item.name)
image .font(.system(size: 16))
.resizable() .foregroundColor(.white)
.aspectRatio(contentMode: .fill) .lineLimit(1)
.frame(width: 370, height: 180)
.clipped() Text(item.status)
default: .font(.system(size: 12))
Image("ph_img_big") .foregroundColor(.white)
.resizable() .lineLimit(1)
.aspectRatio(contentMode: .fill) }
.clipped() .padding(5)
.background(
Color.black.opacity(0.6)
)
.cornerRadius(5)
.padding(8)
} }
.background(GeometryReader { geometry in
} let height = geometry.size.height
.frame(width: 370, height: 180) let minY = geometry.frame(in: .named("indexScrollView")).minY
.overlay(alignment: .topLeading) { let y = minY >= 0 ? minY : minY + height
VStack(alignment: .leading, spacing: 8) {
Text(item.name)
.font(.system(size: 16))
.foregroundColor(.white)
.lineLimit(1)
Text(item.status) Color.clear
.font(.system(size: 12)) .preference(key: DramaGroupElementPreferenceKey.self, value: [ group.group_id : y])
.foregroundColor(.white) })
.lineLimit(1)
}
.padding(5)
.background(
Color.black.opacity(0.6)
)
.cornerRadius(5)
.padding(8)
}
.background(GeometryReader { geometry in
let height = geometry.size.height
let minY = geometry.frame(in: .named("indexScrollView")).minY
let y = minY >= 0 ? minY : minY + height
Color.clear
.preference(key: DramaGroupElementPreferenceKey.self, value: [ group.group_id : y])
})
} }
} }
} }