import SwiftUI import CoreData import Photos struct QRCodeSavedView: View { @EnvironmentObject var languageManager: LanguageManager let qrCodeImage: UIImage let qrCodeContent: String let qrCodeType: QRCodeType let styleData: QRCodeStyleData? let historyItem: HistoryItem? @Environment(\.dismiss) private var dismiss @EnvironmentObject var coreDataManager: CoreDataManager @Environment(\.presentationMode) private var presentationMode @State private var shouldReturnToRoot = false @State private var shouldPopToRoot = false @State private var showingShareSheet = false @State private var showingAlert = false @State private var alertMessage = "" @State private var isSavingToPhotos = false @State private var showingImageComposer = false @State private var showingBackgroundImagePicker = false @State private var selectedBackgroundImage: UIImage? // 用于保存图片的辅助类 private let photoSaver = PhotoSaver() var body: some View { VStack(spacing: 30) { // 二维码图片 qrCodeImageView // 操作按钮 actionButtonsSection Spacer() } .padding() .navigationTitle("qr_code_saved_title".localized) .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarItem(placement: .navigationBarTrailing) { Button("return_home".localized) { // 返回到ContentView,清除导航栈 shouldPopToRoot = true } } } .sheet(isPresented: $showingShareSheet) { ShareSheet(activityItems: [qrCodeImage]) } .alert("tip".localized, isPresented: $showingAlert) { Button("confirm".localized) { } } message: { Text(alertMessage) } .background( NavigationLink( destination: ContentView() .navigationBarBackButtonHidden(true) .navigationBarHidden(true), isActive: $shouldPopToRoot ) { EmptyView() } ) .sheet(isPresented: $showingBackgroundImagePicker) { ImagePicker( onImageSelected: { image in selectedBackgroundImage = image showingImageComposer = true }, shouldProcessImage: false ) } .sheet(isPresented: $showingImageComposer) { if let backgroundImage = selectedBackgroundImage { ImageComposerView(qrCodeImage: qrCodeImage, backgroundImage: backgroundImage) } } } // MARK: - 二维码图片视图 private var qrCodeImageView: some View { VStack(spacing: 16) { Image(uiImage: qrCodeImage) .resizable() .aspectRatio(contentMode: .fit) .frame(width: 300, height: 300) .cornerRadius(16) .shadow(radius: 10) Text("scan_this_qr_code".localized) .font(.headline) .foregroundColor(.secondary) } } // MARK: - 操作按钮区域 private var actionButtonsSection: some View { HStack(spacing: 12) { // 分享按钮 Button(action: { showingShareSheet = true }) { VStack(spacing: 8) { Image(systemName: "square.and.arrow.up") .font(.title2) Text("share".localized) .font(.caption) .fontWeight(.medium) } .frame(maxWidth: .infinity) .padding(.vertical, 16) .background(Color.blue) .foregroundColor(.white) .cornerRadius(12) } // 保存到相册按钮 Button(action: saveToPhotos) { VStack(spacing: 8) { if isSavingToPhotos { ProgressView() .scaleEffect(0.8) .foregroundColor(.white) } else { Image(systemName: "photo") .font(.title2) } Text(isSavingToPhotos ? "saving".localized : "save".localized) .font(.caption) .fontWeight(.medium) } .frame(maxWidth: .infinity) .padding(.vertical, 16) .background(Color.green) .foregroundColor(.white) .cornerRadius(12) } .disabled(isSavingToPhotos) // 添加到图片按钮 Button(action: addToPhotos) { VStack(spacing: 8) { Image(systemName: "plus.rectangle.on.folder") .font(.title2) Text("add_to_picture".localized) .font(.caption) .fontWeight(.medium) } .frame(maxWidth: .infinity) .padding(.vertical, 16) .background(Color.orange) .foregroundColor(.white) .cornerRadius(12) } } } // MARK: - 保存到相册 private func saveToPhotos() { isSavingToPhotos = true // 检查相册权限 let status = PHPhotoLibrary.authorizationStatus() switch status { case .authorized, .limited: saveImageToPhotos() case .notDetermined: PHPhotoLibrary.requestAuthorization { newStatus in DispatchQueue.main.async { if newStatus == .authorized || newStatus == .limited { self.saveImageToPhotos() } else { self.showPermissionAlert() } self.isSavingToPhotos = false } } case .denied, .restricted: DispatchQueue.main.async { self.showPermissionAlert() self.isSavingToPhotos = false } @unknown default: DispatchQueue.main.async { self.showPermissionAlert() self.isSavingToPhotos = false } } } private func saveImageToPhotos() { photoSaver.saveImage(qrCodeImage) { success, error in DispatchQueue.main.async { self.isSavingToPhotos = false if success { self.alertMessage = "qr_code_saved_to_photos".localized } else { self.alertMessage = String(format: "save_failed".localized, error?.localizedDescription ?? "unknown_error".localized) } self.showingAlert = true } } } private func showPermissionAlert() { alertMessage = "photo_permission_required".localized showingAlert = true } // MARK: - 添加到图片 private func addToPhotos() { // 先选择背景图片,然后跳转到图片合成界面 showingBackgroundImagePicker = true } } // MARK: - 图片保存辅助类 class PhotoSaver: NSObject { func saveImage(_ image: UIImage, completion: @escaping (Bool, Error?) -> Void) { UIImageWriteToSavedPhotosAlbum(image, self, #selector(image(_:didFinishSavingWithError:contextInfo:)), nil) self.completion = completion } private var completion: ((Bool, Error?) -> Void)? @objc private func image(_ image: UIImage, didFinishSavingWithError error: Error?, contextInfo: UnsafeRawPointer) { completion?(error == nil, error) } } #Preview { let sampleImage = UIImage(systemName: "qrcode") ?? UIImage() let sampleStyleData = QRCodeStyleData( foregroundColor: "black", backgroundColor: "white", dotType: "square", eyeType: "square", logo: nil, hasCustomLogo: false, customLogoFileName: nil ) return QRCodeSavedView( qrCodeImage: sampleImage, qrCodeContent: "https://example.com", qrCodeType: .url, styleData: sampleStyleData, historyItem: nil ) .environmentObject(CoreDataManager()) .environmentObject(LanguageManager.shared) }