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