diff --git a/MyQrCode/Views/Components/InputComponentFactory.swift b/MyQrCode/Views/Components/InputComponentFactory.swift index eb69b42..6a1c4a0 100644 --- a/MyQrCode/Views/Components/InputComponentFactory.swift +++ b/MyQrCode/Views/Components/InputComponentFactory.swift @@ -102,7 +102,8 @@ struct InputComponentFactory { eventDescription: eventDescription, startDate: startDate, endDate: endDate, - location: location + location: location, + focusedField: focusedCalendarField ) ) @@ -150,7 +151,7 @@ struct InputComponentFactory { } // 获取占位符文本 - private static func getPlaceholderText(for qrCodeType: QRCodeType) -> String { + static func getPlaceholderText(for qrCodeType: QRCodeType) -> String { switch qrCodeType { case .text: return "输入任意文本内容..." diff --git a/MyQrCode/Views/CreateQRCodeView.swift b/MyQrCode/Views/CreateQRCodeView.swift index 93241f7..dcb5b0e 100644 --- a/MyQrCode/Views/CreateQRCodeView.swift +++ b/MyQrCode/Views/CreateQRCodeView.swift @@ -10,11 +10,8 @@ struct CreateQRCodeView: View { // 从类型选择界面传入的参数 let selectedQRCodeType: QRCodeType + // 通用内容输入 @State private var content = "" - @State private var showingAlert = false - @State private var alertMessage = "" - - // 输入焦点,确保进入页面自动弹出键盘 @FocusState private var isContentFieldFocused: Bool // Email相关字段 @@ -23,12 +20,56 @@ struct CreateQRCodeView: View { @State private var emailBody = "" @State private var emailCc = "" @State private var emailBcc = "" - @FocusState private var focusedEmailField: EmailField? + @FocusState private var focusedEmailField: EmailInputView.EmailField? - // Email字段枚举 - private enum EmailField: Hashable { - case address, subject, body, cc, bcc - } + // WiFi相关字段 + @State private var wifiSSID = "" + @State private var wifiPassword = "" + @State private var wifiEncryptionType: WiFiInputView.WiFiEncryptionType = .wpa2 + @FocusState private var focusedWiFiField: WiFiInputView.WiFiField? + + // 联系人相关字段 + @State private var contactFirstName = "" + @State private var contactLastName = "" + @State private var contactPhone = "" + @State private var contactEmail = "" + @State private var contactCompany = "" + @State private var contactTitle = "" + @State private var contactAddress = "" + @State private var contactWebsite = "" + @FocusState private var focusedContactField: ContactInputView.ContactField? + + // 位置相关字段 + @State private var locationLatitude = "" + @State private var locationLongitude = "" + @State private var locationName = "" + @FocusState private var focusedLocationField: LocationInputView.LocationField? + + // 日历相关字段 + @State private var eventTitle = "" + @State private var eventDescription = "" + @State private var eventLocation = "" + @State private var startDate = Date() + @State private var endDate = Date().addingTimeInterval(3600) + @FocusState private var focusedCalendarField: CalendarInputView.CalendarField? + + // 社交平台相关字段 + @State private var socialUsername = "" + @State private var socialMessage = "" + @FocusState private var focusedSocialField: SocialInputView.SocialField? + + // 电话相关字段 + @State private var phoneNumber = "" + @State private var phoneMessage = "" + @FocusState private var focusedPhoneField: PhoneInputView.PhoneField? + + // URL相关字段 + @State private var urlString = "" + @FocusState private var isURLFieldFocused: Bool + + // 通用状态 + @State private var showingAlert = false + @State private var alertMessage = "" var body: some View { VStack(spacing: 0) { @@ -47,345 +88,92 @@ struct CreateQRCodeView: View { Button("确定") { } } message: { Text(alertMessage) } .onAppear { - // 稍延迟以确保进入页面时自动聚焦 - DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { - if selectedQRCodeType == .mail { - focusedEmailField = .address - } else { - isContentFieldFocused = true - } - } + setupInitialFocus() } .onTapGesture { - // 点击外部关闭键盘 - if selectedQRCodeType == .mail { - focusedEmailField = nil - } else { - isContentFieldFocused = false - } + hideKeyboard() } } // MARK: - UI Components - private var emailInputSection: some View { - VStack(spacing: 16) { - // Email地址 (必填) - VStack(alignment: .leading, spacing: 8) { - HStack { - Text("邮箱地址") - .font(.subheadline) - .foregroundColor(.primary) - Text("*") - .foregroundColor(.red) - Spacer() - } - - TextField("user@example.com", text: $emailAddress) - .textFieldStyle(RoundedBorderTextFieldStyle()) - .keyboardType(.emailAddress) - .autocapitalization(.none) - .focused($focusedEmailField, equals: .address) - } - - // 主题 (必填) - VStack(alignment: .leading, spacing: 8) { - HStack { - Text("主题") - .font(.subheadline) - .foregroundColor(.primary) - Text("*") - .foregroundColor(.red) - Spacer() - } - - TextField("邮件主题", text: $emailSubject) - .textFieldStyle(RoundedBorderTextFieldStyle()) - .focused($focusedEmailField, equals: .subject) - } - - // 正文 (必填) - VStack(alignment: .leading, spacing: 8) { - HStack { - Text("正文") - .font(.subheadline) - .foregroundColor(.primary) - Text("*") - .foregroundColor(.red) - Spacer() - } - - ZStack { - TextEditor(text: $emailBody) - .frame(minHeight: 120) - .padding(8) - .background(Color(.systemBackground)) - .cornerRadius(8) - .overlay( - RoundedRectangle(cornerRadius: 8) - .stroke(focusedEmailField == .body ? Color.blue : Color(.systemGray4), lineWidth: 1) - ) - .focused($focusedEmailField, equals: .body) - .onChange(of: emailBody) { newValue in - // 限制最大字符数为1200 - if newValue.count > 1200 { - emailBody = String(newValue.prefix(1200)) - } - } - - // 占位符文本 - if emailBody.isEmpty && focusedEmailField != .body { - VStack { - HStack { - Text("输入邮件正文内容...") - .foregroundColor(.secondary) - .font(.body) - Spacer() - } - Spacer() - } - .padding(16) - .allowsHitTesting(false) - .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading) - } - } - - // 字符计数 - HStack { - Spacer() - Text("\(emailBody.count)/1200") - .font(.caption) - .foregroundColor(emailBody.count >= 1200 ? .orange : .secondary) - } - } - - // CC地址 (可选) - VStack(alignment: .leading, spacing: 8) { - HStack { - Text("抄送地址") - .font(.subheadline) - .foregroundColor(.primary) - Spacer() - } - - TextField("cc@example.com", text: $emailCc) - .textFieldStyle(RoundedBorderTextFieldStyle()) - .keyboardType(.emailAddress) - .autocapitalization(.none) - .focused($focusedEmailField, equals: .cc) - } - - // BCC地址 (可选) - VStack(alignment: .leading, spacing: 8) { - HStack { - Text("密送地址") - .font(.subheadline) - .foregroundColor(.primary) - Spacer() - } - - TextField("bcc@example.com", text: $emailBcc) - .textFieldStyle(RoundedBorderTextFieldStyle()) - .keyboardType(.emailAddress) - .autocapitalization(.none) - .focused($focusedEmailField, equals: .bcc) - } - } - .toolbar { - ToolbarItemGroup(placement: .keyboard) { - Spacer() - Button("完成") { - focusedEmailField = nil - } - .foregroundColor(.blue) - .font(.system(size: 16, weight: .medium)) - } - } - } - private var inputAndPreviewSection: some View { ScrollView { VStack(spacing: 24) { // 输入提示 - VStack(spacing: 12) { - HStack { - Image(systemName: "info.circle") - .font(.caption) - .foregroundColor(.blue) - - Text(getContentHint()) - .font(.caption) - .foregroundColor(.secondary) - .lineLimit(nil) - - Spacer() - } - .padding(.horizontal, 12) - .padding(.vertical, 8) - .background( - RoundedRectangle(cornerRadius: 8) - .fill(Color.blue.opacity(0.1)) - ) - } + InputHintView.info( + hint: getContentHint() + ) .padding(.horizontal, 20) // 内容输入区域 VStack(spacing: 16) { - HStack { - Text(selectedQRCodeType == .mail ? "邮件信息" : "输入内容") - .font(.headline) - .foregroundColor(.primary) - - Spacer() - } + InputTitleView.required( + selectedQRCodeType == .mail ? "邮件信息" : "输入内容", + icon: getInputIcon() + ) + .padding(.horizontal, 20) - if selectedQRCodeType == .mail { - // Email专用输入界面 - emailInputSection - } else { - // 通用输入界面 - VStack(spacing: 8) { - ZStack { - // 输入框主体 - TextEditor(text: $content) - .frame(minHeight: 120) - .padding(8) - .background(Color(.systemBackground)) - .cornerRadius(8) - .overlay( - RoundedRectangle(cornerRadius: 8) - .stroke(isContentFieldFocused ? Color.blue : Color(.systemGray4), lineWidth: 1) - ) - .focused($isContentFieldFocused) - .onChange(of: content) { newValue in - // 限制最大字符数为150 - if newValue.count > 150 { - content = String(newValue.prefix(150)) - } - } - .toolbar { - ToolbarItemGroup(placement: .keyboard) { - Spacer() - Button("完成") { - isContentFieldFocused = false - } - .foregroundColor(.blue) - .font(.system(size: 16, weight: .medium)) - } - } - - // 占位符文本 - 左上角对齐 - if content.isEmpty && !isContentFieldFocused { - VStack { - HStack { - Text(getPlaceholderText()) - .foregroundColor(.secondary) - .font(.body) - Spacer() - } - Spacer() - } - .padding(16) - .allowsHitTesting(false) - .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading) - } - } - - // 字符计数和限制提示 - 输入框底下 - HStack { - Spacer() // Pushes content to the right - - VStack(alignment: .trailing, spacing: 4) { - // 字符限制提示 - if content.count >= 150 { - HStack(spacing: 4) { - Image(systemName: "exclamationmark.triangle") - .font(.caption) - .foregroundColor(.orange) - Text("已达到最大字符数") - .font(.caption) - .foregroundColor(.orange) - } - } else if content.count >= 140 { - HStack(spacing: 4) { - Image(systemName: "info.circle") - .font(.caption) - .foregroundColor(.blue) - Text("接近字符限制") - .font(.caption) - .foregroundColor(.blue) - } - } - - // 字符计数 - Text("\(content.count)/150") - .font(.caption) - .foregroundColor(getCharacterCountColor()) - } - } - } - } + // 使用InputComponentFactory动态选择输入组件 + InputComponentFactory.createInputComponent( + for: selectedQRCodeType, + content: $content, + emailAddress: $emailAddress, + emailSubject: $emailSubject, + emailBody: $emailBody, + emailCc: $emailCc, + emailBcc: $emailBcc, + focusedEmailField: _focusedEmailField, + isContentFieldFocused: _isContentFieldFocused, + ssid: $wifiSSID, + password: $wifiPassword, + encryptionType: $wifiEncryptionType, + focusedWiFiField: _focusedWiFiField, + firstName: $contactFirstName, + lastName: $contactLastName, + phone: $contactPhone, + email: $contactEmail, + company: $contactCompany, + title: $contactTitle, + address: $contactAddress, + website: $contactWebsite, + focusedContactField: _focusedContactField, + latitude: $locationLatitude, + longitude: $locationLongitude, + locationName: $locationName, + focusedLocationField: _focusedLocationField, + eventTitle: $eventTitle, + eventDescription: $eventDescription, + startDate: $startDate, + endDate: $endDate, + location: $eventLocation, + focusedCalendarField: _focusedCalendarField, + username: $socialUsername, + message: $socialMessage, + focusedSocialField: _focusedSocialField, + phoneNumber: $phoneNumber, + phoneMessage: $phoneMessage, + focusedPhoneField: _focusedPhoneField, + url: $urlString, + isUrlFieldFocused: _isURLFieldFocused + ) + .padding(.horizontal, 20) } - .padding(.horizontal, 20) // 预览区域 - if selectedQRCodeType == .mail ? (!emailAddress.isEmpty && !emailSubject.isEmpty && !emailBody.isEmpty) : !content.isEmpty { + if canCreateQRCode() { VStack(spacing: 16) { - HStack { - Text("预览") - .font(.headline) - .foregroundColor(.primary) - - Spacer() - } + InputTitleView.required("预览", icon: "eye") + .padding(.horizontal, 20) - // 二维码预览卡片 - VStack(spacing: 16) { - // 二维码图片 - if let qrImage = generateQRCodeImage() { - Image(uiImage: qrImage) - .interpolation(.none) - .resizable() - .scaledToFit() - .frame(width: 200, height: 200) - .background(Color.white) - .cornerRadius(12) - .shadow(color: .black.opacity(0.1), radius: 8, x: 0, y: 4) - } - - // 内容预览卡片 - VStack(alignment: .leading, spacing: 8) { - HStack { - Text("内容") - .font(.caption) - .foregroundColor(.secondary) - - Spacer() - - Text(selectedQRCodeType.displayName) - .font(.caption) - .padding(.horizontal, 6) - .padding(.vertical, 2) - .background(Color.orange.opacity(0.1)) - .foregroundColor(.orange) - .cornerRadius(4) - } - - Text(formatContentForQRCodeType()) - .font(.body) - .foregroundColor(.primary) - .textSelection(.enabled) - } - .padding() - .background(Color(.systemGray6)) - .cornerRadius(8) - } - .padding() - .background(Color(.systemBackground)) - .cornerRadius(12) - .shadow(color: .black.opacity(0.05), radius: 4, x: 0, y: 2) + // 使用QRCodePreviewView组件 + QRCodePreviewView( + qrCodeImage: generateQRCodeImage(), + formattedContent: formatContentForQRCodeType(), + qrCodeType: selectedQRCodeType + ) + .padding(.horizontal, 20) } - .padding(.horizontal, 20) } Spacer(minLength: 100) @@ -397,133 +185,106 @@ struct CreateQRCodeView: View { // MARK: - Helper Methods - private func canCreateQRCode() -> Bool { - switch selectedQRCodeType { - case .mail: - // Email类型:邮箱地址、主题、正文为必填 - return !emailAddress.isEmpty && !emailSubject.isEmpty && !emailBody.isEmpty - default: - // 其他类型:内容不能为空 - return !content.isEmpty - } - } - - private func getCharacterCountColor() -> Color { - if content.count >= 150 { - return .orange - } else if content.count >= 140 { - return .blue - } else { - return .secondary + private func setupInitialFocus() { + DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { + switch selectedQRCodeType { + case .mail: + focusedEmailField = .address + case .wifi: + focusedWiFiField = .ssid + case .vcard, .mecard: + focusedContactField = .firstName + case .location: + focusedLocationField = .latitude + case .calendar: + focusedCalendarField = .title + case .instagram, .facebook, .spotify, .twitter, .snapchat, .tiktok: + focusedSocialField = .username + case .phone, .sms: + focusedPhoneField = .phoneNumber + case .url: + isURLFieldFocused = true + default: + isContentFieldFocused = true + } } } - private func getContentHint() -> String { + private func hideKeyboard() { switch selectedQRCodeType { - case .text: - return "输入任意文本内容" - case .url: - return "输入网址,如:https://www.example.com" case .mail: - return "填写邮件信息,邮箱地址、主题、正文为必填项" - case .phone: - return "输入电话号码,如:+86 138 0013 8000" - case .sms: - return "输入短信内容,如:Hello World" + focusedEmailField = nil case .wifi: - return "输入WiFi信息,如:SSID:MyWiFi,Password:12345678" - case .vcard: - return "输入联系人信息" - case .mecard: - return "输入联系人信息(简化版)" + focusedWiFiField = nil + case .vcard, .mecard: + focusedContactField = nil case .location: - return "输入地理位置,如:40.7128,-74.0060" + focusedLocationField = nil case .calendar: - return "输入日历事件信息" - case .instagram: - return "输入Instagram用户名或链接" - case .facebook: - return "输入Facebook用户名或链接" - case .spotify: - return "输入Spotify歌曲或播放列表链接" - case .twitter: - return "输入Twitter用户名或链接" - case .whatsapp: - return "输入WhatsApp消息内容" - case .viber: - return "输入Viber消息内容" - case .snapchat: - return "输入Snapchat用户名" - case .tiktok: - return "输入TikTok用户名或链接" + focusedCalendarField = nil + case .instagram, .facebook, .spotify, .twitter, .snapchat, .tiktok: + focusedSocialField = nil + case .phone, .sms: + focusedPhoneField = nil + case .url: + isURLFieldFocused = false + default: + isContentFieldFocused = false } } - private func getPlaceholderText() -> String { + private func getInputIcon() -> String { + switch selectedQRCodeType { + case .mail: return "envelope" + case .wifi: return "wifi" + case .vcard, .mecard: return "person" + case .location: return "location" + case .calendar: return "calendar" + case .instagram, .facebook, .spotify, .twitter, .snapchat, .tiktok: return "globe" + case .phone, .sms: return "phone" + case .url: return "link" + default: return "textformat" + } + } + + private func canCreateQRCode() -> Bool { switch selectedQRCodeType { - case .text: - return "输入任意文本内容..." - case .url: - return "输入网址..." case .mail: - return "输入邮件内容..." - case .phone: - return "输入电话号码..." - case .sms: - return "输入短信内容..." + return !emailAddress.isEmpty && !emailSubject.isEmpty && !emailBody.isEmpty case .wifi: - return "输入WiFi信息..." - case .vcard: - return "输入联系人信息..." - case .mecard: - return "输入联系人信息..." + return !wifiSSID.isEmpty + case .vcard, .mecard: + return !contactFirstName.isEmpty || !contactLastName.isEmpty case .location: - return "输入地理位置..." + return !locationLatitude.isEmpty && !locationLongitude.isEmpty case .calendar: - return "输入日历事件信息..." - case .instagram: - return "输入Instagram信息..." - case .facebook: - return "输入Facebook信息..." - case .spotify: - return "输入Spotify信息..." - case .twitter: - return "输入Twitter信息..." - case .whatsapp: - return "输入WhatsApp信息..." - case .viber: - return "输入Viber信息..." - case .snapchat: - return "输入Snapchat信息..." - case .tiktok: - return "输入TikTok信息..." + return !eventTitle.isEmpty + case .instagram, .facebook, .spotify, .twitter, .snapchat, .tiktok: + return !socialUsername.isEmpty + case .phone, .sms: + return !phoneNumber.isEmpty + case .url: + return !urlString.isEmpty + default: + return !content.isEmpty } } + private func getContentHint() -> String { + InputComponentFactory.getPlaceholderText(for: selectedQRCodeType) + } + private func generateQRCodeImage() -> UIImage? { - // 根据二维码类型检查内容是否为空 - let hasContent: Bool - switch selectedQRCodeType { - case .mail: - hasContent = !emailAddress.isEmpty && !emailSubject.isEmpty && !emailBody.isEmpty - default: - hasContent = !content.isEmpty - } + guard canCreateQRCode() else { return nil } - guard hasContent else { return nil } - - // 根据二维码类型格式化内容 let formattedContent = formatContentForQRCodeType() - - // 生成二维码 let data = formattedContent.data(using: .utf8) let qrFilter = CIFilter.qrCodeGenerator() qrFilter.setValue(data, forKey: "inputMessage") - qrFilter.setValue("H", forKey: "inputCorrectionLevel") // 高纠错级别 + qrFilter.setValue("H", forKey: "inputCorrectionLevel") guard let outputImage = qrFilter.outputImage else { return nil } - // 转换为UIImage let context = CIContext() guard let cgImage = context.createCGImage(outputImage, from: outputImage.extent) else { return nil } @@ -535,7 +296,7 @@ struct CreateQRCodeView: View { case .text: return content case .url: - return content.hasPrefix("http") ? content : "https://\(content)" + return urlString.hasPrefix("http") ? urlString : "https://\(urlString)" case .mail: var mailtoURL = "mailto:\(emailAddress)" var queryParams: [String] = [] @@ -562,35 +323,97 @@ struct CreateQRCodeView: View { return mailtoURL case .phone: - return "tel:\(content)" + return "tel:\(phoneNumber)" case .sms: - return "sms:\(content)" + let smsContent = phoneMessage.isEmpty ? "Hello" : phoneMessage + return "sms:\(phoneNumber):\(smsContent)" case .wifi: - return "WIFI:T:WPA;S:\(content);P:password;;" + return "WIFI:T:\(wifiEncryptionType.rawValue);S:\(wifiSSID);P:\(wifiPassword);;" case .vcard: - return "BEGIN:VCARD\nVERSION:3.0\nFN:\(content)\nEND:VCARD" + var vcard = "BEGIN:VCARD\nVERSION:3.0\n" + if !contactFirstName.isEmpty || !contactLastName.isEmpty { + vcard += "FN:\(contactFirstName) \(contactLastName)\n" + } + if !contactPhone.isEmpty { + vcard += "TEL:\(contactPhone)\n" + } + if !contactEmail.isEmpty { + vcard += "EMAIL:\(contactEmail)\n" + } + if !contactCompany.isEmpty { + vcard += "ORG:\(contactCompany)\n" + } + if !contactTitle.isEmpty { + vcard += "TITLE:\(contactTitle)\n" + } + if !contactAddress.isEmpty { + vcard += "ADR:\(contactAddress)\n" + } + if !contactWebsite.isEmpty { + vcard += "URL:\(contactWebsite)\n" + } + vcard += "END:VCARD" + return vcard case .mecard: - return "MECARD:N:\(content);;" + var mecard = "MECARD:" + if !contactFirstName.isEmpty || !contactLastName.isEmpty { + mecard += "N:\(contactLastName),\(contactFirstName);" + } + if !contactPhone.isEmpty { + mecard += "TEL:\(contactPhone);" + } + if !contactEmail.isEmpty { + mecard += "EMAIL:\(contactEmail);" + } + if !contactCompany.isEmpty { + mecard += "ORG:\(contactCompany);" + } + if !contactAddress.isEmpty { + mecard += "ADR:\(contactAddress);" + } + if !contactWebsite.isEmpty { + mecard += "URL:\(contactWebsite);" + } + mecard += ";" + return mecard case .location: - return "geo:\(content)" + let coords = "\(locationLatitude),\(locationLongitude)" + return locationName.isEmpty ? "geo:\(coords)" : "geo:\(coords)?q=\(locationName)" case .calendar: - return "BEGIN:VEVENT\nSUMMARY:\(content)\nEND:VEVENT" + let dateFormatter = DateFormatter() + dateFormatter.dateFormat = "yyyyMMdd'T'HHmmss'Z'" + dateFormatter.timeZone = TimeZone(abbreviation: "UTC") + + var ical = "BEGIN:VEVENT\n" + ical += "SUMMARY:\(eventTitle)\n" + if !eventDescription.isEmpty { + ical += "DESCRIPTION:\(eventDescription)\n" + } + if !eventLocation.isEmpty { + ical += "LOCATION:\(eventLocation)\n" + } + ical += "DTSTART:\(dateFormatter.string(from: startDate))\n" + ical += "DTEND:\(dateFormatter.string(from: endDate))\n" + ical += "END:VEVENT" + return ical case .instagram: - return "https://instagram.com/\(content)" + return "https://instagram.com/\(socialUsername)" case .facebook: - return "https://facebook.com/\(content)" + return "https://facebook.com/\(socialUsername)" case .spotify: - return content.hasPrefix("http") ? content : "https://open.spotify.com/track/\(content)" + return socialUsername.hasPrefix("http") ? socialUsername : "https://open.spotify.com/track/\(socialUsername)" case .twitter: - return "https://twitter.com/\(content)" + return "https://twitter.com/\(socialUsername)" case .whatsapp: - return "https://wa.me/\(content)" + let message = socialMessage.isEmpty ? "Hello" : socialMessage + return "https://wa.me/\(socialUsername)?text=\(message.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? message)" case .viber: - return "viber://chat?number=\(content)" + let message = socialMessage.isEmpty ? "Hello" : socialMessage + return "viber://chat?number=\(socialUsername)&text=\(message.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? message)" case .snapchat: - return "https://snapchat.com/add/\(content)" + return "https://snapchat.com/add/\(socialUsername)" case .tiktok: - return "https://tiktok.com/@\(content)" + return "https://tiktok.com/@\(socialUsername)" } } @@ -615,6 +438,20 @@ struct CreateQRCodeView: View { mailContent += "\n密送: \(emailBcc)" } historyItem.content = mailContent + case .wifi: + historyItem.content = "WiFi: \(wifiSSID) (\(wifiEncryptionType.displayName))" + case .vcard, .mecard: + historyItem.content = "联系人: \(contactFirstName) \(contactLastName)" + case .location: + historyItem.content = "位置: \(locationLatitude), \(locationLongitude)" + case .calendar: + historyItem.content = "事件: \(eventTitle)" + case .instagram, .facebook, .spotify, .twitter, .snapchat, .tiktok: + historyItem.content = "\(selectedQRCodeType.displayName): \(socialUsername)" + case .phone, .sms: + historyItem.content = "电话: \(phoneNumber)" + case .url: + historyItem.content = "URL: \(urlString)" default: historyItem.content = content } diff --git a/MyQrCode/Views/QRCodeDetailView.swift b/MyQrCode/Views/QRCodeDetailView.swift index f399a7b..502dbaa 100644 --- a/MyQrCode/Views/QRCodeDetailView.swift +++ b/MyQrCode/Views/QRCodeDetailView.swift @@ -169,7 +169,6 @@ struct QRCodeDetailView: View { // MARK: - 原始内容 private var originalContentSection: some View { - #if DEBUG VStack(alignment: .leading, spacing: 12) { HStack { Image(systemName: "doc.text") @@ -200,9 +199,6 @@ struct QRCodeDetailView: View { .background(Color(.systemBackground)) .cornerRadius(12) .shadow(radius: 2) - #else - EmptyView() - #endif } // MARK: - 操作按钮