Refactor CreateCodeView to enhance barcode input validation and user experience; implement dynamic input handling, visual feedback, and improved layout for barcode type selection and content entry.

main
v504 2 months ago
parent dab1808934
commit f048426f6b

@ -0,0 +1,275 @@
import Foundation
// MARK: -
class BarcodeValidator {
// MARK: -
struct ValidationResult {
let isValid: Bool
let formattedContent: String
let errorMessage: String?
let expectedLength: Int?
let allowedCharacters: String?
}
// MARK: -
static func validateBarcode(_ content: String, type: BarcodeType) -> ValidationResult {
let cleanedContent = content.replacingOccurrences(of: " ", with: "")
switch type {
case .ean13:
return validateEAN13(cleanedContent)
case .ean8:
return validateEAN8(cleanedContent)
case .upce:
return validateUPCE(cleanedContent)
case .code39:
return validateCode39(cleanedContent)
case .code128:
return validateCode128(cleanedContent)
case .itf14:
return validateITF14(cleanedContent)
case .pdf417:
return validatePDF417(cleanedContent)
}
}
// MARK: - EAN-13
private static func validateEAN13(_ content: String) -> ValidationResult {
// EAN-13: 13
let pattern = "^[0-9]{13}$"
let isValid = content.range(of: pattern, options: .regularExpression) != nil
if isValid {
return ValidationResult(
isValid: true,
formattedContent: formatEAN13(content),
errorMessage: nil,
expectedLength: 13,
allowedCharacters: "数字 (0-9)"
)
} else {
return ValidationResult(
isValid: false,
formattedContent: content,
errorMessage: "EAN-13必须是13位数字",
expectedLength: 13,
allowedCharacters: "数字 (0-9)"
)
}
}
// MARK: - EAN-8
private static func validateEAN8(_ content: String) -> ValidationResult {
// EAN-8: 8
let pattern = "^[0-9]{8}$"
let isValid = content.range(of: pattern, options: .regularExpression) != nil
if isValid {
return ValidationResult(
isValid: true,
formattedContent: formatEAN8(content),
errorMessage: nil,
expectedLength: 8,
allowedCharacters: "数字 (0-9)"
)
} else {
return ValidationResult(
isValid: false,
formattedContent: content,
errorMessage: "EAN-8必须是8位数字",
expectedLength: 8,
allowedCharacters: "数字 (0-9)"
)
}
}
// MARK: - UPC-E
private static func validateUPCE(_ content: String) -> ValidationResult {
// UPC-E: 8
let pattern = "^[0-9]{8}$"
let isValid = content.range(of: pattern, options: .regularExpression) != nil
if isValid {
return ValidationResult(
isValid: true,
formattedContent: formatUPCE(content),
errorMessage: nil,
expectedLength: 8,
allowedCharacters: "数字 (0-9)"
)
} else {
return ValidationResult(
isValid: false,
formattedContent: content,
errorMessage: "UPC-E必须是8位数字",
expectedLength: 8,
allowedCharacters: "数字 (0-9)"
)
}
}
// MARK: - Code 39
private static func validateCode39(_ content: String) -> ValidationResult {
// Code 39:
let pattern = "^[A-Z0-9\\s\\-\\+\\.\\/\\$\\(\\)\\%\\s]+$"
let isValid = content.range(of: pattern, options: .regularExpression) != nil
if isValid {
return ValidationResult(
isValid: true,
formattedContent: formatCode39(content),
errorMessage: nil,
expectedLength: nil,
allowedCharacters: "字母 (A-Z)、数字 (0-9)、空格、特殊字符 (- + . / $ ( ) %)"
)
} else {
return ValidationResult(
isValid: false,
formattedContent: content,
errorMessage: "Code 39只能包含字母、数字、空格和特殊字符",
expectedLength: nil,
allowedCharacters: "字母 (A-Z)、数字 (0-9)、空格、特殊字符 (- + . / $ ( ) %)"
)
}
}
// MARK: - Code 128
private static func validateCode128(_ content: String) -> ValidationResult {
// Code 128: ASCII
let pattern = "^[\\x00-\\x7F]+$"
let isValid = content.range(of: pattern, options: .regularExpression) != nil
if isValid {
return ValidationResult(
isValid: true,
formattedContent: formatCode128(content),
errorMessage: nil,
expectedLength: nil,
allowedCharacters: "所有ASCII字符 (0-127)"
)
} else {
return ValidationResult(
isValid: false,
formattedContent: content,
errorMessage: "Code 128只能包含ASCII字符",
expectedLength: nil,
allowedCharacters: "所有ASCII字符 (0-127)"
)
}
}
// MARK: - ITF-14
private static func validateITF14(_ content: String) -> ValidationResult {
// ITF-14: 14
let pattern = "^[0-9]{14}$"
let isValid = content.range(of: pattern, options: .regularExpression) != nil
if isValid {
return ValidationResult(
isValid: true,
formattedContent: formatITF14(content),
errorMessage: nil,
expectedLength: 14,
allowedCharacters: "数字 (0-9)"
)
} else {
return ValidationResult(
isValid: false,
formattedContent: content,
errorMessage: "ITF-14必须是14位数字",
expectedLength: 14,
allowedCharacters: "数字 (0-9)"
)
}
}
// MARK: - PDF417
private static func validatePDF417(_ content: String) -> ValidationResult {
// PDF417: ASCII
let pattern = "^[\\x00-\\x7F]+$"
let isValid = content.range(of: pattern, options: .regularExpression) != nil
if isValid {
return ValidationResult(
isValid: true,
formattedContent: formatPDF417(content),
errorMessage: nil,
expectedLength: nil,
allowedCharacters: "所有ASCII字符 (0-127)"
)
} else {
return ValidationResult(
isValid: false,
formattedContent: content,
errorMessage: "PDF417只能包含ASCII字符",
expectedLength: nil,
allowedCharacters: "所有ASCII字符 (0-127)"
)
}
}
// MARK: -
private static func formatEAN13(_ content: String) -> String {
// EAN-13:
let formatted = content.enumerated().map { index, char in
if index == 0 || index == 6 || index == 12 {
return " \(char)"
}
return String(char)
}.joined()
return formatted.trimmingCharacters(in: .whitespaces)
}
private static func formatEAN8(_ content: String) -> String {
// EAN-8:
let formatted = content.enumerated().map { index, char in
if index == 0 || index == 4 {
return " \(char)"
}
return String(char)
}.joined()
return formatted.trimmingCharacters(in: .whitespaces)
}
private static func formatUPCE(_ content: String) -> String {
// UPC-E:
let formatted = content.enumerated().map { index, char in
if index == 0 || index == 4 {
return " \(char)"
}
return String(char)
}.joined()
return formatted.trimmingCharacters(in: .whitespaces)
}
private static func formatCode39(_ content: String) -> String {
// Code 39:
return content.trimmingCharacters(in: .whitespaces)
}
private static func formatCode128(_ content: String) -> String {
// Code 128:
return content.trimmingCharacters(in: .whitespaces)
}
private static func formatITF14(_ content: String) -> String {
// ITF-14:
let formatted = content.enumerated().map { index, char in
if index == 0 || index == 5 || index == 10 {
return " \(char)"
}
return String(char)
}.joined()
return formatted.trimmingCharacters(in: .whitespaces)
}
private static func formatPDF417(_ content: String) -> String {
// PDF417:
return content.trimmingCharacters(in: .whitespaces)
}
}

@ -7,11 +7,6 @@ public enum BarcodeType: String, CaseIterable {
case ean8 = "EAN-8"
case upce = "UPC-E"
case code39 = "Code 39"
case code39Checksum = "Code 39 (Checksum)"
case code39FullASCII = "Code 39 (Full ASCII)"
case code39FullASCIIChecksum = "Code 39 (Full ASCII + Checksum)"
case code93 = "Code 93"
case code93i = "Code 93i"
case code128 = "Code 128"
case itf14 = "ITF-14"
case pdf417 = "PDF417"
@ -22,14 +17,10 @@ public enum BarcodeType: String, CaseIterable {
var icon: String {
switch self {
case .ean13, .ean8, .upce:
case .ean13, .ean8, .upce, .itf14:
return "barcode"
case .code39, .code39Checksum, .code39FullASCII, .code39FullASCIIChecksum:
case .code39, .code128:
return "barcode.viewfinder"
case .code93, .code93i, .code128:
return "barcode.viewfinder"
case .itf14:
return "barcode"
case .pdf417:
return "qrcode.viewfinder"
}

@ -0,0 +1,95 @@
import SwiftUI
// MARK: -
struct BarcodeCharacterHintView: View {
let barcodeType: BarcodeType
var body: some View {
VStack(alignment: .leading, spacing: 8) {
Text("字符类型:")
.font(.caption)
.foregroundColor(.secondary)
LazyVGrid(columns: [
GridItem(.adaptive(minimum: 80), spacing: 8)
], spacing: 6) {
ForEach(getCharacterTypes(), id: \.self) { charType in
HStack(spacing: 4) {
Image(systemName: charType.icon)
.font(.caption2)
.foregroundColor(charType.color)
Text(charType.name)
.font(.caption2)
.foregroundColor(charType.color)
}
.padding(.horizontal, 8)
.padding(.vertical, 4)
.background(
RoundedRectangle(cornerRadius: 6)
.fill(charType.color.opacity(0.1))
)
}
}
}
}
private func getCharacterTypes() -> [CharacterType] {
switch barcodeType {
case .ean13, .ean8, .upce, .itf14:
return [
CharacterType(name: "数字", icon: "number", color: .blue)
]
case .code39:
return [
CharacterType(name: "字母", icon: "character", color: .green),
CharacterType(name: "数字", icon: "number", color: .blue),
CharacterType(name: "特殊字符", icon: "textformat", color: .orange)
]
case .code128:
return [
CharacterType(name: "字母", icon: "character", color: .green),
CharacterType(name: "数字", icon: "number", color: .blue),
CharacterType(name: "符号", icon: "textformat", color: .purple),
CharacterType(name: "控制字符", icon: "command", color: .red)
]
case .pdf417:
return [
CharacterType(name: "字母", icon: "character", color: .green),
CharacterType(name: "数字", icon: "number", color: .blue),
CharacterType(name: "符号", icon: "textformat", color: .purple),
CharacterType(name: "所有ASCII", icon: "globe", color: .indigo)
]
}
}
}
// MARK: -
struct CharacterType: Hashable {
let name: String
let icon: String
let color: Color
// Hashable
func hash(into hasher: inout Hasher) {
hasher.combine(name)
hasher.combine(icon)
}
static func == (lhs: CharacterType, rhs: CharacterType) -> Bool {
return lhs.name == rhs.name && lhs.icon == rhs.icon
}
}
#Preview {
VStack(spacing: 20) {
BarcodeCharacterHintView(barcodeType: .ean13)
BarcodeCharacterHintView(barcodeType: .code39)
BarcodeCharacterHintView(barcodeType: .code128)
BarcodeCharacterHintView(barcodeType: .pdf417)
}
.padding()
}

@ -0,0 +1,94 @@
import SwiftUI
import CoreImage
import CoreImage.CIFilterBuiltins
// MARK: -
struct BarcodePreviewView: View {
let content: String
let barcodeType: BarcodeType
var body: some View {
Group {
if let barcodeImage = generateBarcodeImage() {
Image(uiImage: barcodeImage)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(maxWidth: .infinity)
.background(Color.white)
.cornerRadius(8)
.shadow(color: .black.opacity(0.1), radius: 2, x: 0, y: 1)
} else {
//
VStack(spacing: 8) {
Image(systemName: "barcode.viewfinder")
.font(.system(size: 32))
.foregroundColor(.gray)
Text("无法生成条形码")
.font(.caption)
.foregroundColor(.gray)
Text("请检查输入内容格式")
.font(.caption2)
.foregroundColor(.gray)
}
.frame(maxWidth: .infinity)
.frame(height: 120)
.background(Color(.systemGray5))
.cornerRadius(8)
}
}
}
// MARK: -
private func generateBarcodeImage() -> UIImage? {
guard !content.isEmpty else { return nil }
let context = CIContext()
let filter: CIFilter?
//
switch barcodeType {
case .ean13, .ean8, .upce, .itf14:
filter = CIFilter.code128BarcodeGenerator()
filter?.setValue(content.data(using: .utf8), forKey: "inputMessage")
case .code39:
// Code 39 使 Code 128 Core Image Code 39
filter = CIFilter.code128BarcodeGenerator()
filter?.setValue(content.data(using: .utf8), forKey: "inputMessage")
case .code128:
filter = CIFilter.code128BarcodeGenerator()
filter?.setValue(content.data(using: .utf8), forKey: "inputMessage")
case .pdf417:
filter = CIFilter.pdf417BarcodeGenerator()
filter?.setValue(content.data(using: .utf8), forKey: "inputMessage")
}
guard let filter = filter,
let outputImage = filter.outputImage else { return nil }
//
let scale = CGAffineTransform(scaleX: 3, y: 3)
let scaledImage = outputImage.transformed(by: scale)
// UIImage
guard let cgImage = context.createCGImage(scaledImage, from: scaledImage.extent) else {
return nil
}
return UIImage(cgImage: cgImage)
}
}
#Preview {
VStack(spacing: 20) {
BarcodePreviewView(content: "1234567890123", barcodeType: .ean13)
BarcodePreviewView(content: "12345678", barcodeType: .ean8)
BarcodePreviewView(content: "CODE39", barcodeType: .code39)
BarcodePreviewView(content: "123456789012345678901234567890", barcodeType: .pdf417)
}
.padding()
}

@ -0,0 +1,124 @@
import SwiftUI
// MARK: -
struct BarcodeValidationInfoView: View {
let validationResult: BarcodeValidator.ValidationResult?
let barcodeType: BarcodeType
var body: some View {
VStack(alignment: .leading, spacing: 8) {
if let result = validationResult {
//
HStack(spacing: 8) {
Image(systemName: result.isValid ? "checkmark.circle.fill" : "xmark.circle.fill")
.foregroundColor(result.isValid ? .green : .red)
Text(result.isValid ? "格式正确" : "格式错误")
.font(.caption)
.foregroundColor(result.isValid ? .green : .red)
.fontWeight(.medium)
Spacer()
}
//
if let errorMessage = result.errorMessage {
Text(errorMessage)
.font(.caption)
.foregroundColor(.red)
.padding(.leading, 24)
}
//
VStack(alignment: .leading, spacing: 4) {
if let expectedLength = result.expectedLength {
HStack {
Image(systemName: "number")
.foregroundColor(.blue)
.font(.caption)
Text("长度要求: \(expectedLength)")
.font(.caption)
.foregroundColor(.blue)
}
}
if let allowedCharacters = result.allowedCharacters {
HStack {
Image(systemName: "character")
.foregroundColor(.blue)
.font(.caption)
Text("允许字符: \(allowedCharacters)")
.font(.caption)
.foregroundColor(.blue)
}
}
}
.padding(.leading, 24)
//
if result.isValid && result.formattedContent != "" {
HStack {
Image(systemName: "textformat")
.foregroundColor(.green)
.font(.caption)
Text("格式化: \(result.formattedContent)")
.font(.caption)
.foregroundColor(.green)
.fontWeight(.medium)
}
.padding(.leading, 24)
}
} else {
//
HStack {
Image(systemName: "info.circle")
.foregroundColor(.blue)
.font(.caption)
Text("请输入符合 \(barcodeType.displayName) 格式的内容")
.font(.caption)
.foregroundColor(.blue)
}
}
}
.padding(12)
.background(
RoundedRectangle(cornerRadius: 8)
.fill(Color(.systemGray6))
)
}
}
#Preview {
VStack(spacing: 20) {
//
BarcodeValidationInfoView(
validationResult: BarcodeValidator.ValidationResult(
isValid: true,
formattedContent: "123 4567 8901 2",
errorMessage: nil,
expectedLength: 13,
allowedCharacters: "数字 (0-9)"
),
barcodeType: .ean13
)
//
BarcodeValidationInfoView(
validationResult: BarcodeValidator.ValidationResult(
isValid: false,
formattedContent: "12345",
errorMessage: "EAN-13必须是13位数字",
expectedLength: 13,
allowedCharacters: "数字 (0-9)"
),
barcodeType: .ean13
)
//
BarcodeValidationInfoView(
validationResult: nil,
barcodeType: .code39
)
}
.padding()
}

@ -12,21 +12,53 @@ struct CreateCodeView: View {
@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 {
NavigationView {
Form {
//
Section("数据类型") {
Picker("数据类型", selection: $selectedDataType) {
HStack(spacing: 0) {
ForEach(DataType.allCases, id: \.self) { type in
HStack {
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)
}
.tag(type)
.frame(maxWidth: .infinity)
.padding(.vertical, 12)
.background(
RoundedRectangle(cornerRadius: 8)
.fill(selectedDataType == type ? Color.blue : Color(.systemGray6))
)
}
.buttonStyle(PlainButtonStyle())
}
}
.pickerStyle(SegmentedPickerStyle())
.background(
RoundedRectangle(cornerRadius: 8)
.fill(Color(.systemGray6))
)
.overlay(
RoundedRectangle(cornerRadius: 8)
.stroke(Color(.systemGray4), lineWidth: 0.5)
)
}
//
@ -60,14 +92,101 @@ struct CreateCodeView: View {
//
Section("内容") {
TextField("请输入内容", text: $content)
.frame(minHeight: 80)
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: 8) {
VStack(alignment: .leading, spacing: 12) {
HStack {
Image(systemName: selectedDataType.icon)
Text(selectedDataType.displayName)
@ -91,9 +210,22 @@ struct CreateCodeView: View {
}
}
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))
@ -104,54 +236,182 @@ struct CreateCodeView: View {
.navigationTitle("创建\(selectedDataType.displayName)")
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Button("取消") {
dismiss()
}
}
ToolbarItem(placement: .navigationBarTrailing) {
Button("创建") {
createCode()
}
Button("创建") { createCode() }
.disabled(content.isEmpty)
}
}
.alert("提示", isPresented: $showingAlert) {
Button("确定") { }
} message: {
Text(alertMessage)
} message: { Text(alertMessage) }
.onAppear {
//
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
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 }
//
if selectedDataType == .barcode {
let validation = BarcodeValidator.validateBarcode(content, type: selectedBarcodeType)
if !validation.isValid {
alertMessage = validation.errorMessage ?? "条形码格式不正确"
showingAlert = true
return
}
}
let context = coreDataManager.container.viewContext
let historyItem = HistoryItem(context: context)
historyItem.id = UUID()
historyItem.content = content
historyItem.dataType = selectedDataType.rawValue
historyItem.dataSource = DataSource.created.rawValue
historyItem.createdAt = Date()
historyItem.isFavorite = false
if selectedDataType == .barcode {
historyItem.barcodeType = selectedBarcodeType.rawValue
} else {
historyItem.qrCodeType = selectedQRCodeType.rawValue
}
coreDataManager.addHistoryItem(historyItem)
alertMessage = "\(selectedDataType.displayName)创建成功!"
showingAlert = true
//
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
dismiss()
}
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { dismiss() }
}
}

Loading…
Cancel
Save