From 29ee4ba2f2386af5f7c0f42da3628b8cef866ab0 Mon Sep 17 00:00:00 2001 From: v504 Date: Fri, 22 Aug 2025 09:55:01 +0800 Subject: [PATCH] Refactor CreateCodeView to streamline data type selection and input handling; replace direct state management with parameters for improved modularity and user experience. Update navigation links in HistoryView for consistent code type selection flow. --- MyQrCode/ContentView.swift | 4 +- MyQrCode/Views/CodeContentInputView.swift | 287 ++++++++++++++++ MyQrCode/Views/CodeTypeSelectionView.swift | 134 ++++++++ MyQrCode/Views/CreateCodeView.swift | 367 ++------------------- MyQrCode/Views/HistoryView.swift | 14 +- 5 files changed, 449 insertions(+), 357 deletions(-) create mode 100644 MyQrCode/Views/CodeContentInputView.swift create mode 100644 MyQrCode/Views/CodeTypeSelectionView.swift diff --git a/MyQrCode/ContentView.swift b/MyQrCode/ContentView.swift index 09e3e99..0deaaa5 100644 --- a/MyQrCode/ContentView.swift +++ b/MyQrCode/ContentView.swift @@ -38,8 +38,8 @@ struct ContentView: View { // 功能卡片布局 VStack(spacing: 18) { - // 主功能 - 创建二维码(大卡片) - NavigationLink(destination: CreateCodeView()) { + // 主功能 - 创建二维码(大卡片) + NavigationLink(destination: CodeTypeSelectionView()) { VStack(alignment: .leading, spacing: 20) { HStack { Image(systemName: "qrcode") diff --git a/MyQrCode/Views/CodeContentInputView.swift b/MyQrCode/Views/CodeContentInputView.swift new file mode 100644 index 0000000..a6f7b77 --- /dev/null +++ b/MyQrCode/Views/CodeContentInputView.swift @@ -0,0 +1,287 @@ +import SwiftUI + +// MARK: - 内容输入和预览组件 +struct CodeContentInputView: View { + let selectedDataType: DataType + let selectedBarcodeType: BarcodeType + let selectedQRCodeType: QRCodeType + + @Binding var content: String + @Binding var validationResult: BarcodeValidator.ValidationResult? + @FocusState.Binding var isContentFieldFocused: Bool + + var body: some View { + VStack(spacing: 16) { + // 内容输入区域 + contentInputSection + + // 预览区域 + if !content.isEmpty { + previewSection + } + } + } + + // MARK: - 内容输入区域 + private var contentInputSection: some View { + Section("内容") { + VStack(alignment: .leading, spacing: 12) { + // 输入框和计数布局 + VStack(alignment: .trailing, spacing: 4) { + // 条形码格式提示 + if selectedDataType == .barcode { + HStack { + Image(systemName: "info.circle") + .font(.caption) + .foregroundColor(.blue) + + Text(getBarcodeFormatHint()) + .font(.caption) + .foregroundColor(.secondary) + .lineLimit(2) + + Spacer() + } + .padding(.horizontal, 4) + .padding(.vertical, 6) + .background( + RoundedRectangle(cornerRadius: 6) + .fill(Color.blue.opacity(0.1)) + ) + } + + TextField(getPlaceholderText(), text: $content) + .textFieldStyle(RoundedBorderTextFieldStyle()) + .keyboardType(getKeyboardType()) + .textInputAutocapitalization(getAutocapitalization()) + .disableAutocorrection(true) + .focused($isContentFieldFocused) + .toolbar { + ToolbarItemGroup(placement: .keyboard) { + Spacer() + Button("完成") { + isContentFieldFocused = false + } + .foregroundColor(.blue) + .font(.system(size: 16, weight: .medium)) + } + } + .foregroundColor(.black) + .onChange(of: content) { newValue in + handleContentChange(newValue) + } + + // 计数显示在输入框下方,右对齐 + if let maxLen = getMaxLength(), selectedDataType == .barcode { + Text("\(normalizedInputCount())/\(maxLen)") + .font(.caption2) + .foregroundColor(.blue) + .fontWeight(.medium) + } + } + + // 输入统计与验证状态 + HStack { + if let result = validationResult, result.isValid { + Text("✓ 格式正确") + .font(.caption2) + .foregroundColor(.green) + } else if !content.isEmpty { + Text("⚠ 格式检查中...") + .font(.caption2) + .foregroundColor(.orange) + } + } + + // 条形码验证信息(仅在格式不正确时显示) + if selectedDataType == .barcode && !content.isEmpty && (validationResult == nil || !validationResult!.isValid) { + BarcodeValidationInfoView( + validationResult: validationResult, + barcodeType: selectedBarcodeType + ) + } + } + } + } + + // MARK: - 预览区域 + private var previewSection: some View { + Section("预览") { + VStack(alignment: .leading, spacing: 12) { + HStack { + Image(systemName: selectedDataType.icon) + Text(selectedDataType.displayName) + Spacer() + if selectedDataType == .barcode { + Text(selectedBarcodeType.displayName) + .font(.caption) + .padding(.horizontal, 8) + .padding(.vertical, 2) + .background(Color.green.opacity(0.1)) + .foregroundColor(.green) + .cornerRadius(8) + } else { + Text(selectedQRCodeType.displayName) + .font(.caption) + .padding(.horizontal, 8) + .padding(.vertical, 2) + .background(Color.orange.opacity(0.1)) + .foregroundColor(.orange) + .cornerRadius(8) + } + } + + if selectedDataType == .barcode && !content.isEmpty && isInputComplete() { + // 条形码图片预览(仅在输入完成时显示) + BarcodePreviewView( + content: content, + barcodeType: selectedBarcodeType + ) + .frame(height: 120) + .frame(maxWidth: .infinity) + } else { + // 二维码或文本预览 + Text(content) + .font(.body) + .foregroundColor(.secondary) + .padding() + .frame(maxWidth: .infinity, alignment: .leading) + } + } + .padding() + .background(Color(.systemGray6)) + .cornerRadius(8) + } + } + + // MARK: - 辅助方法 + + private func handleContentChange(_ newValue: String) { + // 针对有固定长度与数字要求的类型,进行输入规范化(仅保留数字并按最大长度截断) + if selectedDataType == .barcode, let maxLen = getMaxLength(), requiresDigitsOnly() { + let digits = newValue.filter { $0.isNumber } + let truncated = String(digits.prefix(maxLen)) + if truncated != newValue { + content = truncated + // 播放输入提示音 + playInputSound() + } + } else if selectedDataType == .barcode { + // 播放输入提示音 + playInputSound() + } + validateBarcodeContent(content) + } + + private func validateBarcodeContent(_ newContent: String) { + guard selectedDataType == .barcode else { return } + validationResult = BarcodeValidator.validateBarcode(newContent, type: selectedBarcodeType) + } + + private func getKeyboardType() -> UIKeyboardType { + guard selectedDataType == .barcode else { return .default } + switch selectedBarcodeType { + case .ean13, .ean8, .upce, .itf14: + return .numberPad + case .code39, .code128, .pdf417: + return .asciiCapable + } + } + + private func getAutocapitalization() -> TextInputAutocapitalization { + guard selectedDataType == .barcode else { return .sentences } + switch selectedBarcodeType { + case .ean13, .ean8, .upce, .itf14: + return .never + case .code39, .code128, .pdf417: + return .characters + } + } + + private func getMaxLength() -> Int? { + guard selectedDataType == .barcode else { return nil } + switch selectedBarcodeType { + case .ean13: return 13 + case .ean8: return 8 + case .upce: return 8 + case .itf14: return 14 + default: return nil + } + } + + private func requiresDigitsOnly() -> Bool { + guard selectedDataType == .barcode else { return false } + switch selectedBarcodeType { + case .ean13, .ean8, .upce, .itf14: + return true + default: + return false + } + } + + private func normalizedInputCount() -> Int { + if requiresDigitsOnly() { + return content.filter { $0.isNumber }.count + } + return content.count + } + + private func getBarcodeFormatHint() -> String { + switch selectedBarcodeType { + case .ean13: + return "请输入13位数字,如:1234567890123" + case .ean8: + return "请输入8位数字,如:12345678" + case .upce: + return "请输入8位数字,如:12345678" + case .code39: + return "请输入字母、数字、空格和特殊字符" + case .code128: + return "请输入任意ASCII字符" + case .itf14: + return "请输入14位数字,如:12345678901234" + case .pdf417: + return "请输入任意ASCII字符" + } + } + + private func getPlaceholderText() -> String { + if selectedDataType == .barcode { + switch selectedBarcodeType { + case .ean13: + return "输入13位数字" + case .ean8: + return "输入8位数字" + case .upce: + return "输入8位数字" + case .code39: + return "输入字母、数字等" + case .code128: + return "输入任意字符" + case .itf14: + return "输入14位数字" + case .pdf417: + return "输入任意字符" + } + } else { + return "请输入内容" + } + } + + private func playInputSound() { + // 使用系统触觉反馈作为输入提示音 + let impactFeedback = UIImpactFeedbackGenerator(style: .light) + impactFeedback.impactOccurred() + } + + private func isInputComplete() -> Bool { + if selectedDataType == .barcode { + // 条形码需要验证格式正确 + return validationResult?.isValid == true + } else { + // 二维码只要有内容就算完成 + return !content.isEmpty + } + } +} + diff --git a/MyQrCode/Views/CodeTypeSelectionView.swift b/MyQrCode/Views/CodeTypeSelectionView.swift new file mode 100644 index 0000000..b473533 --- /dev/null +++ b/MyQrCode/Views/CodeTypeSelectionView.swift @@ -0,0 +1,134 @@ +import SwiftUI + +// MARK: - 数据类型选择界面 +struct CodeTypeSelectionView: View { + @State private var selectedDataType: DataType = .qrcode + @State private var selectedBarcodeType: BarcodeType = .ean13 + @State private var selectedQRCodeType: QRCodeType = .text + + var body: some View { + VStack(spacing: 30) { + // 数据类型选择 + VStack(spacing: 20) { + Text("数据类型") + .font(.headline) + .foregroundColor(.primary) + .frame(maxWidth: .infinity, alignment: .leading) + + HStack(spacing: 0) { + ForEach(DataType.allCases, id: \.self) { type in + Button(action: { + selectedDataType = type + // 添加触觉反馈 + let impactFeedback = UIImpactFeedbackGenerator(style: .light) + impactFeedback.impactOccurred() + }) { + HStack(spacing: 6) { + Image(systemName: type.icon) + .font(.system(size: 16, weight: .medium)) + .foregroundColor(selectedDataType == type ? .white : .primary) + + Text(type.displayName) + .font(.system(size: 15, weight: .medium)) + .foregroundColor(selectedDataType == type ? .white : .primary) + } + .frame(maxWidth: .infinity) + .padding(.vertical, 12) + .background( + RoundedRectangle(cornerRadius: 8) + .fill(selectedDataType == type ? Color.blue : Color(.systemGray6)) + ) + } + .buttonStyle(PlainButtonStyle()) + } + } + .background( + RoundedRectangle(cornerRadius: 8) + .fill(Color(.systemGray6)) + ) + .overlay( + RoundedRectangle(cornerRadius: 8) + .stroke(Color(.systemGray4), lineWidth: 0.5) + ) + } + .padding(.horizontal, 20) + + // 具体类型选择 + VStack(spacing: 20) { + if selectedDataType == .barcode { + VStack(spacing: 12) { + Text("条形码类型") + .font(.headline) + .foregroundColor(.primary) + .frame(maxWidth: .infinity, alignment: .leading) + + Picker("条形码类型", selection: $selectedBarcodeType) { + ForEach(BarcodeType.allCases, id: \.self) { type in + HStack { + Image(systemName: type.icon) + Text(type.displayName) + } + .tag(type) + } + } + .pickerStyle(WheelPickerStyle()) + } + } else { + VStack(spacing: 12) { + Text("二维码类型") + .font(.headline) + .foregroundColor(.primary) + .frame(maxWidth: .infinity, alignment: .leading) + + Picker("二维码类型", selection: $selectedQRCodeType) { + ForEach(QRCodeType.allCases, id: \.self) { type in + HStack { + Image(systemName: type.icon) + Text(type.displayName) + } + .tag(type) + } + } + .pickerStyle(WheelPickerStyle()) + } + } + } + .padding(.horizontal, 20) + + Spacer() + + // 下一步按钮 + NavigationLink( + destination: CreateCodeView( + selectedDataType: selectedDataType, + selectedBarcodeType: selectedBarcodeType, + selectedQRCodeType: selectedQRCodeType + ) + ) { + HStack(spacing: 8) { + Text("下一步") + .font(.system(size: 18, weight: .semibold)) + .foregroundColor(.white) + + Image(systemName: "arrow.right") + .font(.system(size: 16, weight: .medium)) + .foregroundColor(.white) + } + .frame(maxWidth: .infinity) + .padding(.vertical, 16) + .background( + RoundedRectangle(cornerRadius: 12) + .fill(Color.blue) + ) + } + .padding(.horizontal, 20) + .padding(.bottom, 30) + } + .navigationTitle("选择类型") + .navigationBarTitleDisplayMode(.inline) + } +} + +#Preview { + CodeTypeSelectionView() +} diff --git a/MyQrCode/Views/CreateCodeView.swift b/MyQrCode/Views/CreateCodeView.swift index 0b8c5e2..2b58cdd 100644 --- a/MyQrCode/Views/CreateCodeView.swift +++ b/MyQrCode/Views/CreateCodeView.swift @@ -5,233 +5,31 @@ struct CreateCodeView: View { @Environment(\.dismiss) private var dismiss @StateObject private var coreDataManager = CoreDataManager.shared - @State private var selectedDataType: DataType = .qrcode - @State private var selectedBarcodeType: BarcodeType = .ean13 - @State private var selectedQRCodeType: QRCodeType = .text + // 从类型选择界面传入的参数 + let selectedDataType: DataType + let selectedBarcodeType: BarcodeType + let selectedQRCodeType: QRCodeType @State private var content = "" @State private var showingAlert = false @State private var alertMessage = "" // 条形码验证相关状态 @State private var validationResult: BarcodeValidator.ValidationResult? - @State private var showValidationInfo = false // 输入焦点,确保进入页面自动弹出键盘 @FocusState private var isContentFieldFocused: Bool var body: some View { Form { - // 数据类型选择 - Section("数据类型") { - HStack(spacing: 0) { - ForEach(DataType.allCases, id: \.self) { type in - Button(action: { - selectedDataType = type - isContentFieldFocused = true - // 添加触觉反馈 - let impactFeedback = UIImpactFeedbackGenerator(style: .light) - impactFeedback.impactOccurred() - }) { - HStack(spacing: 6) { - Image(systemName: type.icon) - .font(.system(size: 16, weight: .medium)) - .foregroundColor(selectedDataType == type ? .white : .primary) - - Text(type.displayName) - .font(.system(size: 15, weight: .medium)) - .foregroundColor(selectedDataType == type ? .white : .primary) - } - .frame(maxWidth: .infinity) - .padding(.vertical, 12) - .background( - RoundedRectangle(cornerRadius: 8) - .fill(selectedDataType == type ? Color.blue : Color(.systemGray6)) - ) - } - .buttonStyle(PlainButtonStyle()) - } - } - .background( - RoundedRectangle(cornerRadius: 8) - .fill(Color(.systemGray6)) - ) - .overlay( - RoundedRectangle(cornerRadius: 8) - .stroke(Color(.systemGray4), lineWidth: 0.5) - ) - } - - // 具体类型选择 - if selectedDataType == .barcode { - Section("条形码类型") { - Picker("条形码类型", selection: $selectedBarcodeType) { - ForEach(BarcodeType.allCases, id: \.self) { type in - HStack { - Image(systemName: type.icon) - Text(type.displayName) - } - .tag(type) - } - } - .pickerStyle(WheelPickerStyle()) - } - } else { - Section("二维码类型") { - Picker("二维码类型", selection: $selectedQRCodeType) { - ForEach(QRCodeType.allCases, id: \.self) { type in - HStack { - Image(systemName: type.icon) - Text(type.displayName) - } - .tag(type) - } - } - .pickerStyle(WheelPickerStyle()) - } - } - - // 内容输入 - Section("内容") { - VStack(alignment: .leading, spacing: 12) { - // 输入框和计数布局 - VStack(alignment: .trailing, spacing: 4) { - // 条形码格式提示 - if selectedDataType == .barcode { - HStack { - Image(systemName: "info.circle") - .font(.caption) - .foregroundColor(.blue) - - Text(getBarcodeFormatHint()) - .font(.caption) - .foregroundColor(.secondary) - .lineLimit(2) - - Spacer() - } - .padding(.horizontal, 4) - .padding(.vertical, 6) - .background( - RoundedRectangle(cornerRadius: 6) - .fill(Color.blue.opacity(0.1)) - ) - } - - TextField(getPlaceholderText(), text: $content) - .textFieldStyle(RoundedBorderTextFieldStyle()) - .keyboardType(getKeyboardType()) - .textInputAutocapitalization(getAutocapitalization()) - .disableAutocorrection(true) - .focused($isContentFieldFocused) - .toolbar { - ToolbarItemGroup(placement: .keyboard) { - Spacer() - Button("完成") { - isContentFieldFocused = false - } - .foregroundColor(.blue) - .font(.system(size: 16, weight: .medium)) - } - } - .foregroundColor(.black) - .onChange(of: content) { newValue in - // 针对有固定长度与数字要求的类型,进行输入规范化(仅保留数字并按最大长度截断) - if selectedDataType == .barcode, let maxLen = getMaxLength(), requiresDigitsOnly() { - let digits = newValue.filter { $0.isNumber } - let truncated = String(digits.prefix(maxLen)) - if truncated != newValue { - content = truncated - // 播放输入提示音 - playInputSound() - } - } else if selectedDataType == .barcode { - // 播放输入提示音 - playInputSound() - } - validateBarcodeContent(content) - } - - // 计数显示在输入框下方,右对齐 - if let maxLen = getMaxLength(), selectedDataType == .barcode { - Text("\(normalizedInputCount())/\(maxLen)") - .font(.caption2) - .foregroundColor(.blue) - .fontWeight(.medium) - } - } - - // 输入统计与验证状态 - HStack { - if let result = validationResult, result.isValid { - Text("✓ 格式正确") - .font(.caption2) - .foregroundColor(.green) - } else if !content.isEmpty { - Text("⚠ 格式检查中...") - .font(.caption2) - .foregroundColor(.orange) - } - } - - // 条形码验证信息(仅在格式不正确时显示) - if selectedDataType == .barcode && !content.isEmpty && (validationResult == nil || !validationResult!.isValid) { - BarcodeValidationInfoView( - validationResult: validationResult, - barcodeType: selectedBarcodeType - ) - } - } - } - - // 预览 - if !content.isEmpty { - Section("预览") { - VStack(alignment: .leading, spacing: 12) { - HStack { - Image(systemName: selectedDataType.icon) - Text(selectedDataType.displayName) - Spacer() - if selectedDataType == .barcode { - Text(selectedBarcodeType.displayName) - .font(.caption) - .padding(.horizontal, 8) - .padding(.vertical, 2) - .background(Color.green.opacity(0.1)) - .foregroundColor(.green) - .cornerRadius(8) - } else { - Text(selectedQRCodeType.displayName) - .font(.caption) - .padding(.horizontal, 8) - .padding(.vertical, 2) - .background(Color.orange.opacity(0.1)) - .foregroundColor(.orange) - .cornerRadius(8) - } - } - - if selectedDataType == .barcode && !content.isEmpty && isInputComplete() { - // 条形码图片预览(仅在输入完成时显示) - BarcodePreviewView( - content: content, - barcodeType: selectedBarcodeType - ) - .frame(height: 120) - .frame(maxWidth: .infinity) - } else { - // 二维码或文本预览 - Text(content) - .font(.body) - .foregroundColor(.secondary) - .padding() - .frame(maxWidth: .infinity, alignment: .leading) - } - } - .padding() - .background(Color(.systemGray6)) - .cornerRadius(8) - } - } + // 内容输入和预览组件 + CodeContentInputView( + selectedDataType: selectedDataType, + selectedBarcodeType: selectedBarcodeType, + selectedQRCodeType: selectedQRCodeType, + content: $content, + validationResult: $validationResult, + isContentFieldFocused: $isContentFieldFocused + ) } .navigationTitle("创建\(selectedDataType.displayName)") .navigationBarTitleDisplayMode(.inline) @@ -250,140 +48,12 @@ struct CreateCodeView: View { isContentFieldFocused = true } } - .onChange(of: selectedDataType) { _ in - isContentFieldFocused = true - } - .onChange(of: selectedBarcodeType) { _ in - isContentFieldFocused = true - } .onTapGesture { // 点击外部关闭键盘 isContentFieldFocused = false } } - // MARK: - 条形码验证方法 - private func validateBarcodeContent(_ newContent: String) { - guard selectedDataType == .barcode else { return } - validationResult = BarcodeValidator.validateBarcode(newContent, type: selectedBarcodeType) - // 如果验证通过,自动格式化内容 - if let result = validationResult, result.isValid { - content = result.formattedContent - } - } - - // MARK: - 键盘配置方法 - private func getKeyboardType() -> UIKeyboardType { - guard selectedDataType == .barcode else { return .default } - switch selectedBarcodeType { - case .ean13, .ean8, .upce, .itf14: - return .numberPad - case .code39, .code128, .pdf417: - return .asciiCapable - } - } - - private func getAutocapitalization() -> TextInputAutocapitalization { - guard selectedDataType == .barcode else { return .sentences } - switch selectedBarcodeType { - case .ean13, .ean8, .upce, .itf14: - return .never - case .code39, .code128, .pdf417: - return .characters - } - } - - // MARK: - 计数/规则 - private func getMaxLength() -> Int? { - guard selectedDataType == .barcode else { return nil } - switch selectedBarcodeType { - case .ean13: return 13 - case .ean8: return 8 - case .upce: return 8 - case .itf14: return 14 - default: return nil - } - } - - private func requiresDigitsOnly() -> Bool { - guard selectedDataType == .barcode else { return false } - switch selectedBarcodeType { - case .ean13, .ean8, .upce, .itf14: - return true - default: - return false - } - } - - private func normalizedInputCount() -> Int { - if requiresDigitsOnly() { - return content.filter { $0.isNumber }.count - } - return content.count - } - - // MARK: - 条形码格式提示 - private func getBarcodeFormatHint() -> String { - switch selectedBarcodeType { - case .ean13: - return "请输入13位数字,如:1234567890123" - case .ean8: - return "请输入8位数字,如:12345678" - case .upce: - return "请输入8位数字,如:12345678" - case .code39: - return "请输入字母、数字、空格和特殊字符" - case .code128: - return "请输入任意ASCII字符" - case .itf14: - return "请输入14位数字,如:12345678901234" - case .pdf417: - return "请输入任意ASCII字符" - } - } - - // MARK: - 输入框占位符文本 - private func getPlaceholderText() -> String { - if selectedDataType == .barcode { - switch selectedBarcodeType { - case .ean13: - return "输入13位数字" - case .ean8: - return "输入8位数字" - case .upce: - return "输入8位数字" - case .code39: - return "输入字母、数字等" - case .code128: - return "输入任意字符" - case .itf14: - return "输入14位数字" - case .pdf417: - return "输入任意字符" - } - } else { - return "请输入内容" - } - } - - // MARK: - 播放输入提示音 - private func playInputSound() { - // 使用系统触觉反馈作为输入提示音 - let impactFeedback = UIImpactFeedbackGenerator(style: .light) - impactFeedback.impactOccurred() - } - - // MARK: - 判断输入是否完成 - private func isInputComplete() -> Bool { - if selectedDataType == .barcode { - // 条形码需要验证格式正确 - return validationResult?.isValid == true - } else { - // 二维码只要有内容就算完成 - return !content.isEmpty - } - } - private func createCode() { guard !content.isEmpty else { return } // 如果是条形码,验证格式 @@ -411,10 +81,17 @@ struct CreateCodeView: View { coreDataManager.addHistoryItem(historyItem) alertMessage = "\(selectedDataType.displayName)创建成功!" showingAlert = true - DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { dismiss() } + // 创建成功后返回主页 + DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { + dismiss() // 关闭创建界面,返回到类型选择界面 + } } } #Preview { - CreateCodeView() + CreateCodeView( + selectedDataType: .barcode, + selectedBarcodeType: .ean13, + selectedQRCodeType: .text + ) } diff --git a/MyQrCode/Views/HistoryView.swift b/MyQrCode/Views/HistoryView.swift index 88f3727..beb5ed7 100644 --- a/MyQrCode/Views/HistoryView.swift +++ b/MyQrCode/Views/HistoryView.swift @@ -5,7 +5,7 @@ struct HistoryView: View { @StateObject private var coreDataManager = CoreDataManager.shared @State private var searchText = "" @State private var selectedFilter: HistoryFilter = .all - @State private var showingCreateSheet = false + @State private var itemToDelete: HistoryItem? @State private var showingDeleteAlert = false @State private var showingClearConfirmSheet = false @@ -154,18 +154,14 @@ struct HistoryView: View { } } - Button(action: { - showingCreateSheet = true - }) { + NavigationLink(destination: CodeTypeSelectionView()) { Image(systemName: "plus") } } } } } - .sheet(isPresented: $showingCreateSheet) { - CreateCodeView() - } + .sheet(isPresented: $showingClearConfirmSheet) { ClearHistoryConfirmView( isPresented: $showingClearConfirmSheet, @@ -378,9 +374,7 @@ struct HistoryView: View { .foregroundColor(.gray) .multilineTextAlignment(.center) - Button(action: { - showingCreateSheet = true - }) { + NavigationLink(destination: CodeTypeSelectionView()) { HStack { Image(systemName: "plus.circle.fill") Text("创建第一个记录")