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.
MyQRCode/docs/SCANNER_TO_QRCODE_DETAIL_RE...

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
}
.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模态展示

  • 优点:简单实现,覆盖整个屏幕
  • 缺点:模态展示,用户体验不够流畅
  • 优点:原生导航体验,支持返回手势,更流畅
  • 缺点:需要处理返回时的状态重置

返回时重新扫描机制

触发时机

  • 用户点击返回按钮
  • 用户使用返回手势
  • 详情页面消失时

重置内容

.onDisappear {
    // 从详情页返回时,重新开始扫描
    logInfo("🔄 从详情页返回,重新开始扫描", className: "ScannerView")
    resetToScanning()
}

重置过程

  1. 重置 UI 状态(showPreviewPause = false
  2. 重置扫描状态(resetDetection()
  3. 重新开始扫描(restartScanning()
  4. 延迟检查会话状态

向后兼容性

  • 保留了原有的 NotificationCenter 通知机制
  • 其他依赖扫描结果的组件仍然可以正常工作
  • 不影响现有的扫描和检测逻辑

文件修改

  • 主要文件MyQrCode/ScannerView/ScannerView.swift
  • 新增导入import CoreData
  • 状态变量navigateToDetailselectedHistoryItem
  • 新增方法createHistoryItem(from:)
  • 导航方式:从 .sheet 改为 NavigationLink
  • 返回处理:添加 .onDisappear 回调

依赖关系

  • CoreDataManager.shared:用于保存历史记录
  • QRCodeParser:用于解析二维码类型
  • HistoryItemCore Data 实体模型
  • QRCodeDetailView:详情页面组件

测试建议

  1. 测试单个二维码扫描的自动跳转
  2. 测试多个二维码的用户选择跳转
  3. 测试条形码扫描的跳转
  4. 验证历史记录的正确保存
  5. 检查详情页面的完整显示
  6. 测试返回时的重新扫描功能
  7. 验证导航的流畅性

注意事项

  • 确保 Core Data 模型正确配置
  • 验证 QRCodeParser 的可用性
  • 测试不同设备方向的兼容性
  • 检查内存使用情况(避免内存泄漏)
  • 确保返回时扫描状态正确重置
  • 验证导航栈的正确管理

更新日志

v2.0 (最新)

  • 将 sheet 展示改为 NavigationLink 导航
  • 添加返回时自动重新扫描功能
  • 优化用户体验和导航流畅性

v1.0

  • 实现扫描结果跳转详情页
  • 自动保存历史记录
  • 智能条码类型识别