修复相机历史导入页网格缩略图重叠与溢出问题。

采用 1:1 方形容器约束单元格布局,并统一网格间距与边距常量。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-06 11:49:01 +08:00
parent be9c844bd3
commit 39333e5fd8
4 changed files with 75 additions and 45 deletions

View File

@ -0,0 +1,11 @@
import SwiftUI
///
enum CameraHistoryImportDesign {
static let gridColumns = 3
static let gridHorizontalSpacing: CGFloat = 2
static let gridVerticalSpacing: CGFloat = 2
static let contentHorizontalPadding: CGFloat = 12
static let sectionSpacing: CGFloat = 12
static let thumbnailCornerRadius: CGFloat = 4
}

View File

@ -11,51 +11,61 @@ struct CameraHistoryImportPhotoCell: View {
@State private var thumbnail: UIImage? @State private var thumbnail: UIImage?
var body: some View { var body: some View {
ZStack(alignment: .topTrailing) { Color.clear
Group { .aspectRatio(1, contentMode: .fit)
if let thumbnail { .overlay {
Image(uiImage: thumbnail) thumbnailContent
.resizable() .frame(maxWidth: .infinity, maxHeight: .infinity)
.scaledToFill() }
} else { .clipShape(RoundedRectangle(cornerRadius: CameraHistoryImportDesign.thumbnailCornerRadius))
Color.gray.opacity(0.15) .overlay(alignment: .topTrailing) {
.overlay { statusBadge
ProgressView() }
.scaleEffect(0.7) .contentShape(Rectangle())
} .onTapGesture {
guard !isImported else { return }
onToggle()
}
.task(id: photo.id) {
guard thumbnail == nil else { return }
if let data = await thumbnailProvider(), let image = UIImage(data: data) {
thumbnail = image
} }
} }
.frame(maxWidth: .infinity) }
.aspectRatio(1, contentMode: .fit)
.clipped()
if isImported { @ViewBuilder
Text("已导入") private var thumbnailContent: some View {
.font(.system(size: 10, weight: .medium)) if let thumbnail {
.foregroundStyle(.white) Image(uiImage: thumbnail)
.padding(.horizontal, 6) .resizable()
.padding(.vertical, 3) .scaledToFill()
.background(Color.black.opacity(0.55)) } else {
.clipShape(RoundedRectangle(cornerRadius: 4)) Color.gray.opacity(0.15)
.padding(6) .overlay {
} else { ProgressView()
Image(systemName: isSelected ? "checkmark.circle.fill" : "circle") .scaleEffect(0.7)
.font(.system(size: 22)) }
.foregroundStyle(isSelected ? AppDesign.primary : .white)
.shadow(radius: 2)
.padding(6)
}
} }
.contentShape(Rectangle()) }
.onTapGesture {
guard !isImported else { return } @ViewBuilder
onToggle() private var statusBadge: some View {
} if isImported {
.task(id: photo.id) { Text("已导入")
guard thumbnail == nil else { return } .font(.system(size: 10, weight: .medium))
if let data = await thumbnailProvider(), let image = UIImage(data: data) { .foregroundStyle(.white)
thumbnail = image .padding(.horizontal, 6)
} .padding(.vertical, 3)
.background(Color.black.opacity(0.55))
.clipShape(RoundedRectangle(cornerRadius: 4))
.padding(6)
} else {
Image(systemName: isSelected ? "checkmark.circle.fill" : "circle")
.font(.system(size: 22))
.foregroundStyle(isSelected ? AppDesign.primary : .white)
.shadow(color: .black.opacity(0.35), radius: 2, x: 0, y: 1)
.padding(6)
} }
} }
} }

View File

@ -21,8 +21,9 @@ struct CameraHistoryImportSectionHeader: View {
.foregroundStyle(AppDesign.primary) .foregroundStyle(AppDesign.primary)
} }
} }
.padding(.horizontal, 12) .padding(.horizontal, CameraHistoryImportDesign.contentHorizontalPadding)
.padding(.vertical, 8) .padding(.vertical, 8)
.frame(maxWidth: .infinity, alignment: .leading)
.background(WiredTransferDesign.pageBackground) .background(WiredTransferDesign.pageBackground)
} }
} }

View File

@ -70,10 +70,10 @@ struct CameraHistoryImportView: View {
private func photoList(sections: [CameraPhotoSection]) -> some View { private func photoList(sections: [CameraPhotoSection]) -> some View {
ScrollView { ScrollView {
LazyVStack(spacing: 12, pinnedViews: [.sectionHeaders]) { LazyVStack(spacing: CameraHistoryImportDesign.sectionSpacing, pinnedViews: [.sectionHeaders]) {
ForEach(sections) { section in ForEach(sections) { section in
Section { Section {
LazyVGrid(columns: [GridItem(.flexible()), GridItem(.flexible()), GridItem(.flexible())], spacing: 2) { LazyVGrid(columns: gridColumns, spacing: CameraHistoryImportDesign.gridVerticalSpacing) {
ForEach(section.photos, id: \.id) { photo in ForEach(section.photos, id: \.id) { photo in
CameraHistoryImportPhotoCell( CameraHistoryImportPhotoCell(
photo: photo, photo: photo,
@ -94,10 +94,18 @@ struct CameraHistoryImportView: View {
} }
} }
} }
.padding(.horizontal, 2) .padding(.horizontal, CameraHistoryImportDesign.contentHorizontalPadding)
.padding(.bottom, 16)
} }
} }
private var gridColumns: [GridItem] {
Array(
repeating: GridItem(.flexible(), spacing: CameraHistoryImportDesign.gridHorizontalSpacing),
count: CameraHistoryImportDesign.gridColumns
)
}
private func emptyView(message: String) -> some View { private func emptyView(message: String) -> some View {
VStack(spacing: 16) { VStack(spacing: 16) {
Text(message) Text(message)