import SwiftUI struct MediaUploadDemo: View { @StateObject private var uploadManager = MediaUploadManager() @State private var showMediaPicker = false @State private var showUploadAlert = false @State private var isUploading = false var body: some View { NavigationView { VStack(spacing: 20) { // 上传按钮 Button(action: { showMediaPicker = true }) { Label("添加图片或视频", systemImage: "plus.circle.fill") .font(.headline) .frame(maxWidth: .infinity) .padding() .background(Color.blue) .foregroundColor(.white) .cornerRadius(10) } .padding(.horizontal) .sheet(isPresented: $showMediaPicker) { MediaPickerWithLogging( selectedMedia: $uploadManager.selectedMedia, selectionLimit: 10, onDismiss: { showMediaPicker = false // 当媒体选择器关闭时,如果有选中的媒体,开始上传 if !uploadManager.selectedMedia.isEmpty { isUploading = true uploadManager.startUpload() } } ) } // 预览区域 if uploadManager.selectedMedia.isEmpty { VStack(spacing: 16) { Image(systemName: "photo.on.rectangle.angled") .font(.system(size: 60)) .foregroundColor(.gray) Text("暂无媒体文件") .font(.headline) .foregroundColor(.gray) } .frame(maxWidth: .infinity, maxHeight: .infinity) } else { ScrollView { LazyVGrid(columns: [GridItem(.adaptive(minimum: 120), spacing: 10)], spacing: 10) { ForEach(0.. Double? in if case .uploading(let progress) = status { return progress } return nil }).first { ProgressView(value: progress, total: 1.0) .padding(.horizontal) Text("上传中 \(Int(progress * 100))%") .font(.subheadline) .foregroundColor(.gray) } else { ProgressView() .progressViewStyle(CircularProgressViewStyle()) .scaleEffect(1.5) Text("正在准备上传...") .font(.subheadline) .foregroundColor(.gray) .padding(.top, 8) } } .frame(maxWidth: .infinity) .padding() } } .alert(isPresented: $showUploadAlert) { Alert( title: Text(uploadManager.isAllUploaded ? "上传完成" : "上传状态"), message: Text(uploadManager.isAllUploaded ? "所有文件上传完成!" : "正在处理上传..."), dismissButton: .default(Text("确定")) ) } .onChange(of: uploadManager.uploadStatus) { _ in // 检查是否所有上传都已完成或失败 let allFinished = uploadManager.uploadStatus.values.allSatisfy { status in if case .completed = status { return true } if case .failed = status { return true } return false } if allFinished && !uploadManager.uploadStatus.isEmpty { isUploading = false showUploadAlert = true } } } } } // 媒体项视图 struct MediaItemView: View { let media: MediaType let status: MediaUploadStatus var body: some View { ZStack(alignment: .bottom) { // 缩略图 if let thumbnail = media.thumbnail { Image(uiImage: thumbnail) .resizable() .scaledToFill() .frame(width: 120, height: 120) .cornerRadius(8) .clipped() // 视频标识 if media.isVideo { Image(systemName: "play.circle.fill") .font(.system(size: 30)) .foregroundColor(.white) .shadow(radius: 5) } // 上传状态 VStack { Spacer() if case .uploading(let progress) = status { ProgressView(value: progress, total: 1.0) .progressViewStyle(LinearProgressViewStyle()) .frame(height: 4) .padding(.horizontal, 4) } else if case .completed = status { Image(systemName: "checkmark.circle.fill") .foregroundColor(.green) .padding(4) .background(Circle().fill(Color.white)) } else if case .failed = status { Image(systemName: "exclamationmark.circle.fill") .foregroundColor(.red) .padding(4) .background(Circle().fill(Color.white)) } } .padding(4) } } .frame(width: 120, height: 120) .overlay( RoundedRectangle(cornerRadius: 8) .stroke(Color.gray.opacity(0.3), lineWidth: 1) ) } } // 预览 #Preview { MediaUploadDemo() .environmentObject(AuthState.shared) }