Enhance HistoryItemRow in HistoryView to include navigation links for barcode details, improving user interaction and data type handling.
parent
f23fb833f9
commit
6e08511157
@ -0,0 +1,352 @@
|
||||
import SwiftUI
|
||||
import CoreData
|
||||
|
||||
struct BarcodeDetailView: View {
|
||||
let historyItem: HistoryItem
|
||||
@StateObject private var coreDataManager = CoreDataManager.shared
|
||||
@State private var barcodeImage: UIImage?
|
||||
@State private var showingShareSheet = false
|
||||
@State private var showingAlert = false
|
||||
@State private var alertMessage = ""
|
||||
|
||||
var body: some View {
|
||||
ScrollView {
|
||||
VStack(spacing: 20) {
|
||||
// 条形码图片
|
||||
barcodeImageView
|
||||
|
||||
// 条形码类型信息
|
||||
barcodeTypeSection
|
||||
|
||||
// 条形码内容信息
|
||||
barcodeContentSection
|
||||
|
||||
// 原始内容
|
||||
originalContentSection
|
||||
|
||||
// 操作按钮
|
||||
actionButtonsSection
|
||||
}
|
||||
.padding()
|
||||
}
|
||||
.navigationTitle("条形码详情")
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .navigationBarTrailing) {
|
||||
Button(action: {
|
||||
showingShareSheet = true
|
||||
}) {
|
||||
Image(systemName: "square.and.arrow.up")
|
||||
}
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
generateBarcodeImage()
|
||||
}
|
||||
.sheet(isPresented: $showingShareSheet) {
|
||||
ShareSheet(activityItems: [historyItem.content ?? ""])
|
||||
}
|
||||
.alert("提示", isPresented: $showingAlert) {
|
||||
Button("确定") { }
|
||||
} message: {
|
||||
Text(alertMessage)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - 条形码图片视图
|
||||
private var barcodeImageView: some View {
|
||||
VStack(spacing: 16) {
|
||||
if let barcodeImage = barcodeImage {
|
||||
Image(uiImage: barcodeImage)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fit)
|
||||
.frame(height: 120)
|
||||
.cornerRadius(12)
|
||||
.shadow(radius: 8)
|
||||
} else {
|
||||
RoundedRectangle(cornerRadius: 12)
|
||||
.fill(Color.gray.opacity(0.3))
|
||||
.frame(height: 120)
|
||||
.overlay(
|
||||
ProgressView()
|
||||
.scaleEffect(1.5)
|
||||
)
|
||||
}
|
||||
|
||||
Text("扫描此条形码")
|
||||
.font(.caption)
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - 条形码类型信息
|
||||
private var barcodeTypeSection: some View {
|
||||
VStack(alignment: .leading, spacing: 12) {
|
||||
HStack {
|
||||
Image(systemName: "barcode")
|
||||
.font(.title2)
|
||||
.foregroundColor(.green)
|
||||
|
||||
Text("条形码类型")
|
||||
.font(.headline)
|
||||
|
||||
Spacer()
|
||||
}
|
||||
|
||||
if let barcodeTypeString = historyItem.barcodeType {
|
||||
HStack {
|
||||
Image(systemName: getBarcodeIcon(for: barcodeTypeString))
|
||||
.font(.title3)
|
||||
.foregroundColor(.green)
|
||||
|
||||
Text(barcodeTypeString)
|
||||
.font(.title3)
|
||||
.fontWeight(.medium)
|
||||
|
||||
Spacer()
|
||||
}
|
||||
.padding()
|
||||
.background(Color.green.opacity(0.1))
|
||||
.cornerRadius(8)
|
||||
}
|
||||
}
|
||||
.padding()
|
||||
.background(Color(.systemBackground))
|
||||
.cornerRadius(12)
|
||||
.shadow(radius: 2)
|
||||
}
|
||||
|
||||
// MARK: - 条形码内容信息
|
||||
private var barcodeContentSection: some View {
|
||||
VStack(alignment: .leading, spacing: 12) {
|
||||
HStack {
|
||||
Image(systemName: "info.circle")
|
||||
.font(.title2)
|
||||
.foregroundColor(.blue)
|
||||
|
||||
Text("条形码内容")
|
||||
.font(.headline)
|
||||
|
||||
Spacer()
|
||||
}
|
||||
|
||||
if let content = historyItem.content {
|
||||
VStack(alignment: .leading, spacing: 8) {
|
||||
HStack {
|
||||
Image(systemName: "number")
|
||||
.font(.title3)
|
||||
.foregroundColor(.blue)
|
||||
|
||||
Text("内容长度: \(content.count) 字符")
|
||||
.font(.title3)
|
||||
.fontWeight(.medium)
|
||||
|
||||
Spacer()
|
||||
}
|
||||
|
||||
Text("数据内容")
|
||||
.font(.subheadline)
|
||||
.foregroundColor(.secondary)
|
||||
.padding(.top, 4)
|
||||
}
|
||||
.padding()
|
||||
.background(Color.blue.opacity(0.1))
|
||||
.cornerRadius(8)
|
||||
}
|
||||
}
|
||||
.padding()
|
||||
.background(Color(.systemBackground))
|
||||
.cornerRadius(12)
|
||||
.shadow(radius: 2)
|
||||
}
|
||||
|
||||
// MARK: - 原始内容
|
||||
private var originalContentSection: some View {
|
||||
VStack(alignment: .leading, spacing: 12) {
|
||||
HStack {
|
||||
Image(systemName: "doc.text")
|
||||
.font(.title2)
|
||||
.foregroundColor(.purple)
|
||||
|
||||
Text("原始内容")
|
||||
.font(.headline)
|
||||
|
||||
Spacer()
|
||||
}
|
||||
|
||||
if let content = historyItem.content {
|
||||
ScrollView {
|
||||
Text(content)
|
||||
.font(.system(.body, design: .monospaced))
|
||||
.foregroundColor(.secondary)
|
||||
.multilineTextAlignment(.leading)
|
||||
.padding()
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
}
|
||||
.frame(maxHeight: 200)
|
||||
.background(Color.purple.opacity(0.1))
|
||||
.cornerRadius(8)
|
||||
}
|
||||
}
|
||||
.padding()
|
||||
.background(Color(.systemBackground))
|
||||
.cornerRadius(12)
|
||||
.shadow(radius: 2)
|
||||
}
|
||||
|
||||
// MARK: - 操作按钮
|
||||
private var actionButtonsSection: some View {
|
||||
VStack(spacing: 12) {
|
||||
// 收藏按钮
|
||||
Button(action: toggleFavorite) {
|
||||
HStack {
|
||||
Image(systemName: historyItem.isFavorite ? "heart.fill" : "heart")
|
||||
.foregroundColor(historyItem.isFavorite ? .red : .gray)
|
||||
|
||||
Text(historyItem.isFavorite ? "取消收藏" : "收藏")
|
||||
.fontWeight(.medium)
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding()
|
||||
.background(historyItem.isFavorite ? Color.red.opacity(0.1) : Color.gray.opacity(0.1))
|
||||
.foregroundColor(historyItem.isFavorite ? .red : .gray)
|
||||
.cornerRadius(10)
|
||||
}
|
||||
|
||||
// 复制内容按钮
|
||||
Button(action: copyContent) {
|
||||
HStack {
|
||||
Image(systemName: "doc.on.doc")
|
||||
.foregroundColor(.blue)
|
||||
|
||||
Text("复制内容")
|
||||
.fontWeight(.medium)
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding()
|
||||
.background(Color.blue.opacity(0.1))
|
||||
.foregroundColor(.blue)
|
||||
.cornerRadius(10)
|
||||
}
|
||||
|
||||
// 分享条形码图片按钮
|
||||
if barcodeImage != nil {
|
||||
Button(action: {
|
||||
showingShareSheet = true
|
||||
}) {
|
||||
HStack {
|
||||
Image(systemName: "photo")
|
||||
.foregroundColor(.green)
|
||||
|
||||
Text("分享条形码图片")
|
||||
.fontWeight(.medium)
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding()
|
||||
.background(Color.green.opacity(0.1))
|
||||
.foregroundColor(.green)
|
||||
.cornerRadius(10)
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding()
|
||||
.background(Color(.systemBackground))
|
||||
.cornerRadius(12)
|
||||
.shadow(radius: 2)
|
||||
}
|
||||
|
||||
// MARK: - 生成条形码图片
|
||||
private func generateBarcodeImage() {
|
||||
guard let content = historyItem.content else { return }
|
||||
|
||||
// 使用条形码生成器
|
||||
let barcodeType = historyItem.barcodeType ?? ""
|
||||
let size = CGSize(width: 300, height: 120)
|
||||
|
||||
if let image = BarcodeGenerator.shared.generateBarcode(from: content, type: barcodeType, size: size) {
|
||||
self.barcodeImage = image
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - 获取条形码图标
|
||||
private func getBarcodeIcon(for type: String) -> String {
|
||||
return BarcodeGenerator.shared.getBarcodeIcon(for: type)
|
||||
}
|
||||
|
||||
// MARK: - 切换收藏状态
|
||||
private func toggleFavorite() {
|
||||
historyItem.isFavorite.toggle()
|
||||
coreDataManager.save()
|
||||
|
||||
let message = historyItem.isFavorite ? "已添加到收藏" : "已取消收藏"
|
||||
alertMessage = message
|
||||
showingAlert = true
|
||||
}
|
||||
|
||||
// MARK: - 复制内容
|
||||
private func copyContent() {
|
||||
if let content = historyItem.content {
|
||||
UIPasteboard.general.string = content
|
||||
alertMessage = "内容已复制到剪贴板"
|
||||
showingAlert = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - 分享表单
|
||||
struct BarcodeShareSheet: UIViewControllerRepresentable {
|
||||
let activityItems: [Any]
|
||||
|
||||
func makeUIViewController(context: Context) -> UIActivityViewController {
|
||||
let controller = UIActivityViewController(activityItems: activityItems, applicationActivities: nil)
|
||||
return controller
|
||||
}
|
||||
|
||||
func updateUIViewController(_ uiViewController: UIActivityViewController, context: Context) {}
|
||||
}
|
||||
|
||||
#Preview("EAN-13") {
|
||||
let ctx = PreviewData.context
|
||||
let item = PreviewData.ean13Sample(in: ctx)
|
||||
return NavigationView { BarcodeDetailView(historyItem: item) }
|
||||
}
|
||||
|
||||
#Preview("Code 128") {
|
||||
let ctx = PreviewData.context
|
||||
let item = PreviewData.code128Sample(in: ctx)
|
||||
return NavigationView { BarcodeDetailView(historyItem: item) }
|
||||
}
|
||||
|
||||
// MARK: - Preview Data
|
||||
private enum PreviewData {
|
||||
static let context: NSManagedObjectContext = {
|
||||
let container = NSPersistentContainer(name: "MyQrCode")
|
||||
let description = NSPersistentStoreDescription()
|
||||
description.type = NSInMemoryStoreType
|
||||
container.persistentStoreDescriptions = [description]
|
||||
container.loadPersistentStores { _, _ in }
|
||||
return container.viewContext
|
||||
}()
|
||||
|
||||
private static func makeBaseItem(in context: NSManagedObjectContext, content: String, barcodeType: BarcodeType, favorite: Bool = false) -> HistoryItem {
|
||||
let item = HistoryItem(context: context)
|
||||
item.id = UUID()
|
||||
item.content = content
|
||||
item.dataType = DataType.barcode.rawValue
|
||||
item.dataSource = DataSource.created.rawValue
|
||||
item.createdAt = Date()
|
||||
item.isFavorite = favorite
|
||||
item.barcodeType = barcodeType.rawValue
|
||||
return item
|
||||
}
|
||||
|
||||
static func ean13Sample(in context: NSManagedObjectContext) -> HistoryItem {
|
||||
let content = "1234567890128"
|
||||
return makeBaseItem(in: context, content: content, barcodeType: .ean13, favorite: true)
|
||||
}
|
||||
|
||||
static func code128Sample(in context: NSManagedObjectContext) -> HistoryItem {
|
||||
let content = "ABC123"
|
||||
return makeBaseItem(in: context, content: content, barcodeType: .code128)
|
||||
}
|
||||
}
|
Loading…
Reference in new issue