You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
6.0 KiB
6.0 KiB
ScannerView 扫描结果跳转 QRCodeDetailView 功能
概述
本次更新修改了 ScannerView.swift
,使其在扫描到二维码或条形码结果时,能够自动跳转到 QRCodeDetailView.swift
详情页面,而不是仅仅发送通知。
主要功能
1. 自动跳转详情页
- 当用户选择扫描到的条码时,自动跳转到二维码详情页面
- 支持单个条码自动选择和多个条码手动选择
- 使用
NavigationLink
进行页面导航(非模态展示)
2. 自动保存历史记录
- 扫描到的条码自动保存到 Core Data 历史记录
- 数据来源标记为 "scanned"(扫描获得)
- 自动识别条码类型(二维码/条形码)
3. 智能类型识别
- 二维码:自动解析内容类型(Wi-Fi、URL、SMS、vCard等)
- 条形码:保存原始类型信息
- 使用
QRCodeParser
进行智能解析
4. 返回时自动重新扫描
- 从详情页返回时自动重新开始扫描
- 重置所有扫描状态
- 提供流畅的用户体验
技术实现
新增状态变量
@State private var navigateToDetail = false
@State private var selectedHistoryItem: HistoryItem?
修改扫描结果处理
private func handleCodeSelection(_ selectedCode: DetectedCode) {
// 创建 HistoryItem 并保存到 Core Data
let historyItem = createHistoryItem(from: selectedCode)
// 设置选中的历史记录项并导航到详情页
selectedHistoryItem = historyItem
navigateToDetail = true
// 发送通知(保持向后兼容)
NotificationCenter.default.post(name: .scannerDidScanCode, object: formattedResult)
}
新增历史记录创建方法
private func createHistoryItem(from detectedCode: DetectedCode) -> HistoryItem {
let context = CoreDataManager.shared.container.viewContext
let historyItem = HistoryItem(context: context)
// 设置基本信息
historyItem.id = UUID()
historyItem.content = detectedCode.content
historyItem.dataType = DataType.qrcode.rawValue
historyItem.dataSource = DataSource.scanned.rawValue
historyItem.createdAt = Date()
historyItem.isFavorite = false
// 智能类型识别
if detectedCode.type.lowercased().contains("qr") || detectedCode.type.lowercased().contains("二维码") {
let parsedData = QRCodeParser.parseQRCode(detectedCode.content)
historyItem.qrCodeType = parsedData.type.rawValue
} else {
historyItem.barcodeType = detectedCode.type
}
// 保存到 Core Data
CoreDataManager.shared.addHistoryItem(historyItem)
return historyItem
}
使用 NavigationLink 进行导航
.background(
NavigationLink(
destination: Group {
if let historyItem = selectedHistoryItem {
QRCodeDetailView(historyItem: historyItem)
.onDisappear {
// 从详情页返回时,重新开始扫描
logInfo("🔄 从详情页返回,重新开始扫描", className: "ScannerView")
resetToScanning()
}
}
},
isActive: $navigateToDetail
) {
EmptyView()
}
)
用户体验流程
- 扫描阶段:用户使用扫描器扫描二维码/条形码
- 结果检测:系统检测到条码,暂停预览
- 选择确认:
- 单个条码:1秒后自动选择
- 多个条码:用户手动点击选择点
- 自动跳转:选择后自动导航到详情页
- 详情展示:显示条码图片、类型、解析信息、操作按钮等
- 返回扫描:用户返回时自动重新开始扫描
导航方式对比
之前使用 Sheet(模态展示)
- 优点:简单实现,覆盖整个屏幕
- 缺点:模态展示,用户体验不够流畅
现在使用 NavigationLink(页面导航)
- 优点:原生导航体验,支持返回手势,更流畅
- 缺点:需要处理返回时的状态重置
返回时重新扫描机制
触发时机
- 用户点击返回按钮
- 用户使用返回手势
- 详情页面消失时
重置内容
.onDisappear {
// 从详情页返回时,重新开始扫描
logInfo("🔄 从详情页返回,重新开始扫描", className: "ScannerView")
resetToScanning()
}
重置过程
- 重置 UI 状态(
showPreviewPause = false
) - 重置扫描状态(
resetDetection()
) - 重新开始扫描(
restartScanning()
) - 延迟检查会话状态
向后兼容性
- 保留了原有的
NotificationCenter
通知机制 - 其他依赖扫描结果的组件仍然可以正常工作
- 不影响现有的扫描和检测逻辑
文件修改
- 主要文件:
MyQrCode/ScannerView/ScannerView.swift
- 新增导入:
import CoreData
- 状态变量:
navigateToDetail
、selectedHistoryItem
- 新增方法:
createHistoryItem(from:)
- 导航方式:从
.sheet
改为NavigationLink
- 返回处理:添加
.onDisappear
回调
依赖关系
CoreDataManager.shared
:用于保存历史记录QRCodeParser
:用于解析二维码类型HistoryItem
:Core Data 实体模型QRCodeDetailView
:详情页面组件
测试建议
- 测试单个二维码扫描的自动跳转
- 测试多个二维码的用户选择跳转
- 测试条形码扫描的跳转
- 验证历史记录的正确保存
- 检查详情页面的完整显示
- 测试返回时的重新扫描功能
- 验证导航的流畅性
注意事项
- 确保 Core Data 模型正确配置
- 验证
QRCodeParser
的可用性 - 测试不同设备方向的兼容性
- 检查内存使用情况(避免内存泄漏)
- 确保返回时扫描状态正确重置
- 验证导航栈的正确管理
更新日志
v2.0 (最新)
- 将 sheet 展示改为 NavigationLink 导航
- 添加返回时自动重新扫描功能
- 优化用户体验和导航流畅性
v1.0
- 实现扫描结果跳转详情页
- 自动保存历史记录
- 智能条码类型识别