From 76976b5ec273695724eaccff5db2051e93ed12d2 Mon Sep 17 00:00:00 2001 From: v504 Date: Tue, 26 Aug 2025 18:25:56 +0800 Subject: [PATCH] Enhance QRCodeDetailView and QRCodeStyleView to support navigation and customization of QR code styles. Introduce new properties for existing style data and history items, allowing for better management of QR code customization. Update navigation logic and add a new button for decorating codes, improving user experience in QR code creation and editing. --- MyQrCode/Views/CreateQRCodeView.swift | 2 +- MyQrCode/Views/QRCodeDetailView.swift | 141 ++++++++++++++++++-------- MyQrCode/Views/QRCodeStyleView.swift | 113 ++++++++++++++++++++- 3 files changed, 212 insertions(+), 44 deletions(-) diff --git a/MyQrCode/Views/CreateQRCodeView.swift b/MyQrCode/Views/CreateQRCodeView.swift index 373c61e..479453c 100644 --- a/MyQrCode/Views/CreateQRCodeView.swift +++ b/MyQrCode/Views/CreateQRCodeView.swift @@ -97,7 +97,7 @@ struct CreateQRCodeView: View { } message: { Text(alertMessage) } .background( NavigationLink( - destination: QRCodeStyleView(qrCodeContent: generateQRCodeContent(), qrCodeType: selectedQRCodeType), + destination: QRCodeStyleView(qrCodeContent: generateQRCodeContent(), qrCodeType: selectedQRCodeType, existingStyleData: nil, historyItem: nil), isActive: $navigateToStyleView ) { EmptyView() diff --git a/MyQrCode/Views/QRCodeDetailView.swift b/MyQrCode/Views/QRCodeDetailView.swift index f4d0751..204cacf 100644 --- a/MyQrCode/Views/QRCodeDetailView.swift +++ b/MyQrCode/Views/QRCodeDetailView.swift @@ -10,15 +10,13 @@ struct QRCodeDetailView: View { @State private var showingShareSheet = false @State private var showingAlert = false @State private var alertMessage = "" + @State private var navigateToStyleView = false var body: some View { ScrollView { VStack(spacing: 20) { // 二维码图片 qrCodeStyleSection - - // 二维码类型信息 - qrCodeTypeSection // 解析后的详细信息 parsedInfoSection @@ -28,10 +26,13 @@ struct QRCodeDetailView: View { // 操作按钮 actionButtonsSection + + // Decorate code按钮 + decorateCodeButton } .padding() } - .navigationTitle("二维码详情") + .navigationTitle(getNavigationTitle()) .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarItem(placement: .navigationBarTrailing) { @@ -53,6 +54,19 @@ struct QRCodeDetailView: View { } message: { Text(alertMessage) } + .background( + NavigationLink( + destination: QRCodeStyleView( + qrCodeContent: historyItem.content ?? "", + qrCodeType: getQRCodeType(), + existingStyleData: getStyleData(), + historyItem: historyItem + ), + isActive: $navigateToStyleView + ) { + EmptyView() + } + ) } // MARK: - 二维码图片视图 @@ -81,43 +95,7 @@ struct QRCodeDetailView: View { } } - // MARK: - 二维码类型信息 - private var qrCodeTypeSection: some View { - VStack(alignment: .leading, spacing: 12) { - HStack { - Image(systemName: "qrcode") - .font(.title2) - .foregroundColor(.blue) - - Text("二维码类型") - .font(.headline) - - Spacer() - } - - if let qrCodeTypeString = historyItem.qrCodeType, - let qrCodeType = QRCodeType(rawValue: qrCodeTypeString) { - HStack { - Image(systemName: qrCodeType.icon) - .font(.title3) - .foregroundColor(.orange) - - Text(qrCodeType.displayName) - .font(.title3) - .fontWeight(.medium) - - Spacer() - } - .padding() - .background(Color.orange.opacity(0.1)) - .cornerRadius(8) - } - } - .padding() - .background(Color(.systemBackground)) - .cornerRadius(12) - .shadow(radius: 2) - } + // MARK: - 解析后的详细信息 private var parsedInfoSection: some View { @@ -704,4 +682,85 @@ extension QRCodeDetailView { } return logoString } + + // MARK: - 获取二维码类型 + private func getQRCodeType() -> QRCodeType { + if let qrCodeTypeString = historyItem.qrCodeType, + let qrCodeType = QRCodeType(rawValue: qrCodeTypeString) { + return qrCodeType + } + return .text // 默认返回text类型 + } + + // MARK: - 获取导航标题 + private func getNavigationTitle() -> String { + if let qrCodeTypeString = historyItem.qrCodeType, + let qrCodeType = QRCodeType(rawValue: qrCodeTypeString) { + return qrCodeType.displayName + } + return "二维码详情" + } + + // MARK: - Decorate code按钮 + private var decorateCodeButton: some View { + VStack(spacing: 16) { + Button(action: { + navigateToCustomStyle() + }) { + HStack(spacing: 12) { + Image(systemName: "paintpalette.fill") + .font(.title2) + .foregroundColor(.white) + + Text("Decorate code") + .font(.headline) + .fontWeight(.semibold) + .foregroundColor(.white) + + Spacer() + + Image(systemName: "chevron.right") + .font(.system(size: 14, weight: .medium)) + .foregroundColor(.white.opacity(0.8)) + } + .padding(.horizontal, 20) + .padding(.vertical, 16) + .background( + LinearGradient( + gradient: Gradient(colors: [Color.purple, Color.blue]), + startPoint: .leading, + endPoint: .trailing + ) + ) + .cornerRadius(12) + .shadow(color: .purple.opacity(0.3), radius: 8, x: 0, y: 4) + } + .buttonStyle(PlainButtonStyle()) + + // 如果有现有样式,显示提示 + if getStyleData() != nil { + HStack { + Image(systemName: "info.circle.fill") + .font(.caption) + .foregroundColor(.orange) + + Text("此二维码已有自定义样式,点击可重新编辑") + .font(.caption) + .foregroundColor(.secondary) + + Spacer() + } + .padding(.horizontal, 4) + } + } + .padding() + .background(Color(.systemBackground)) + .cornerRadius(12) + .shadow(radius: 2) + } + + // MARK: - 跳转到自定义样式界面 + private func navigateToCustomStyle() { + navigateToStyleView = true + } } diff --git a/MyQrCode/Views/QRCodeStyleView.swift b/MyQrCode/Views/QRCodeStyleView.swift index 9e14058..604b04a 100644 --- a/MyQrCode/Views/QRCodeStyleView.swift +++ b/MyQrCode/Views/QRCodeStyleView.swift @@ -38,6 +38,8 @@ enum TabType: String, CaseIterable { struct QRCodeStyleView: View { let qrCodeContent: String let qrCodeType: QRCodeType + let existingStyleData: QRCodeStyleData? // 可选的现有样式数据 + let historyItem: HistoryItem? // 可选的现有历史记录项 @Environment(\.dismiss) private var dismiss @EnvironmentObject var coreDataManager: CoreDataManager @@ -128,6 +130,7 @@ struct QRCodeStyleView: View { } .onAppear { checkPhotoLibraryPermission() + initializeExistingStyle() } .sheet(isPresented: $showingImagePicker) { ImagePicker( @@ -539,6 +542,34 @@ struct QRCodeStyleView: View { + // MARK: - 初始化现有样式 + private func initializeExistingStyle() { + guard let existingStyle = existingStyleData else { return } + + // 设置现有样式 + if let foregroundColor = QRCodeColor(rawValue: existingStyle.foregroundColor) { + selectedForegroundColor = foregroundColor + } + if let backgroundColor = QRCodeColor(rawValue: existingStyle.backgroundColor) { + selectedBackgroundColor = backgroundColor + } + if let dotType = QRCodeDotType(rawValue: existingStyle.dotType) { + selectedDotType = dotType + } + if let eyeType = QRCodeEyeType(rawValue: existingStyle.eyeType) { + selectedEyeType = eyeType + } + + // 设置Logo + if existingStyle.hasCustomLogo { + // 加载自定义Logo + customLogoImage = existingStyle.customLogoImage + } else if let logoString = existingStyle.logo, + let logo = QRCodeLogo(rawValue: logoString) { + selectedLogo = logo + } + } + // MARK: - 保存二维码 private func saveQRCode() { // 生成二维码图片 @@ -548,7 +579,11 @@ struct QRCodeStyleView: View { UIImageWriteToSavedPhotosAlbum(qrCodeImage, nil, nil, nil) // 保存到历史记录 - saveToHistory() + if historyItem != nil { + updateExistingHistory() + } else { + saveToHistory() + } dismiss() } @@ -654,6 +689,80 @@ struct QRCodeStyleView: View { } } + // MARK: - 更新现有历史记录 + private func updateExistingHistory() { + guard let existingHistoryItem = historyItem else { return } + + // 确保在主线程上执行Core Data操作 + DispatchQueue.main.async { + do { + let context = self.coreDataManager.container.viewContext + + // 保存二维码样式数据 + var logoIdentifier: String? = nil + var hasCustomLogo = false + var customLogoFileName: String? = nil + + if let customLogo = self.customLogoImage { + // 自定义Logo:保存到文件系统 + let fileName = "custom_\(UUID().uuidString).png" + logoIdentifier = "custom_\(UUID().uuidString)" + hasCustomLogo = true + customLogoFileName = fileName + + // 保存图片到文件系统 + self.saveCustomLogoToFile(customLogo, fileName: fileName) + print("🖼️ 自定义Logo已保存到文件:\(fileName)") + } else if let selectedLogo = self.selectedLogo { + // 预设Logo + logoIdentifier = selectedLogo.rawValue + hasCustomLogo = false + print("🏷️ 使用预设Logo:\(selectedLogo.rawValue)") + } + + let styleData = QRCodeStyleData( + foregroundColor: self.selectedForegroundColor.rawValue, + backgroundColor: self.selectedBackgroundColor.rawValue, + dotType: self.selectedDotType.rawValue, + eyeType: self.selectedEyeType.rawValue, + logo: logoIdentifier, + hasCustomLogo: hasCustomLogo, + customLogoFileName: customLogoFileName + ) + + print("🎨 样式数据更新成功:\(styleData.styleDescription)") + + // 将样式数据转换为JSON字符串 + do { + let jsonData = try JSONEncoder().encode(styleData) + let jsonString = String(data: jsonData, encoding: .utf8) ?? "" + existingHistoryItem.qrCodeStyleData = jsonString + print("✅ 样式数据已更新到历史记录项") + } catch { + print("❌ 样式数据JSON编码失败:\(error)") + } + + // 保存到Core Data + try context.save() + print("✅ 二维码样式更新成功") + + // 强制刷新历史记录 + self.coreDataManager.objectWillChange.send() + + } catch { + print("❌ Core Data更新失败:\(error.localizedDescription)") + print("❌ 错误详情:\(error)") + + // 如果是NSError,打印更多信息 + if let nsError = error as NSError? { + print("❌ 错误域:\(nsError.domain)") + print("❌ 错误代码:\(nsError.code)") + print("❌ 用户信息:\(nsError.userInfo)") + } + } + } + } + // MARK: - 权限检查 private func checkPhotoLibraryPermission() { let status = PHPhotoLibrary.authorizationStatus() @@ -948,6 +1057,6 @@ struct ImagePicker: UIViewControllerRepresentable { // MARK: - 预览 #Preview { - QRCodeStyleView(qrCodeContent: "https://www.example.com", qrCodeType: .url) + QRCodeStyleView(qrCodeContent: "https://www.example.com", qrCodeType: .url, existingStyleData: nil, historyItem: nil) .environmentObject(CoreDataManager.shared) }