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_VIEW_NAVIGATION_REA...

5.8 KiB

ScannerView 导航方式修改说明

🎯 修改目标

ScannerView 的展示方式从 sheet 模态弹窗改为 NavigationLink 导航方式,提供更好的用户体验和导航一致性。

🔄 主要修改内容

1. ContentView.swift 的修改

移除的状态变量

// 移除
@State private var showScanner = false

修改扫描按钮

// 修改前:使用 Button + sheet
Button(action: {
    showScanner = true
}) {
    // 按钮内容
}
.sheet(isPresented: $showScanner) {
    ScannerView()
}

// 修改后:使用 NavigationLink
NavigationLink(destination: ScannerView()) {
    // 按钮内容
}

移除 sheet 修饰符

// 移除
.sheet(isPresented: $showScanner) {
    ScannerView()
}

2. ScannerView.swift 的修改

移除环境变量

// 移除
@Environment(\.dismiss) private var dismiss

添加导航标题和样式

.navigationTitle("扫描器")
.navigationBarTitleDisplayMode(.inline)
.navigationBarBackButtonHidden(false)

修改关闭逻辑

// 修改前
onClose: { dismiss() }

// 修改后
onClose: { /* 导航会自动返回 */ }

// 修改前
dismiss()

// 修改后
// 使用导航返回不需要手动dismiss

更新预览

#if DEBUG
struct ScannerView_Previews: PreviewProvider {
    static var previews: some View {
        NavigationView {
            ScannerView()
        }
    }
}
#endif

3. ScanningOverlayView.swift 的修改

移除 onClose 参数

// 修改前
struct ScanningOverlayView: View {
    let showPreviewPause: Bool
    @Binding var selectedStyle: ScanningLineStyle
    let detectedCodesCount: Int
    let onClose: () -> Void  // 移除
}

// 修改后
struct ScanningOverlayView: View {
    let showPreviewPause: Bool
    @Binding var selectedStyle: ScanningLineStyle
    let detectedCodesCount: Int
}

移除关闭按钮

// 修改前
if !showPreviewPause {
    Button("close_button".localized) {
        onClose()
    }
    // 按钮样式
}

// 修改后
// 移除关闭按钮,因为现在使用导航返回

更新调用方式

// 修改前
ScanningOverlayView(
    showPreviewPause: showPreviewPause,
    selectedStyle: $selectedScanningStyle,
    detectedCodesCount: scannerViewModel.detectedCodes.count,
    onClose: { dismiss() }
)

// 修改后
ScanningOverlayView(
    showPreviewPause: showPreviewPause,
    selectedStyle: $selectedScanningStyle,
    detectedCodesCount: scannerViewModel.detectedCodes.count
)

🚀 修改的优势

1. 用户体验改进

  • 导航一致性: 与应用的导航结构保持一致
  • 返回手势: 支持 iOS 的滑动返回手势
  • 导航历史: 用户可以清楚地看到导航层级

2. 界面布局优化

  • 全屏显示: 扫描器可以充分利用屏幕空间
  • 状态栏: 保持状态栏的显示,提供更好的系统集成
  • 导航栏: 显示标题和返回按钮,提供清晰的上下文

3. 代码简化

  • 移除状态管理: 不需要管理 showScanner 状态
  • 简化回调: 不需要 onClose 回调函数
  • 自动返回: 导航系统自动处理返回逻辑

4. 系统集成

  • 系统导航: 利用 iOS 原生的导航机制
  • 内存管理: 系统自动管理视图的生命周期
  • 转场动画: 使用系统标准的导航转场动画

📱 界面变化对比

修改前 (Sheet 方式)

  • 模态弹窗覆盖整个屏幕
  • 需要手动关闭或 dismiss
  • 不支持滑动返回手势
  • 状态栏可能被隐藏

修改后 (Navigation 方式)

  • 集成到导航栈中
  • 自动显示返回按钮
  • 支持滑动返回手势
  • 保持状态栏显示
  • 显示导航标题

🔧 技术实现细节

NavigationLink(destination: ScannerView()) {
    HStack {
        Image(systemName: "camera.fill")
        Text("start_scanning".localized)
    }
    // 按钮样式
}

2. 导航标题设置

.navigationTitle("扫描器")
.navigationBarTitleDisplayMode(.inline)
.navigationBarBackButtonHidden(false)

3. 自动返回机制

  • 扫描完成后,用户可以通过返回按钮或手势返回
  • 不需要手动调用 dismiss()
  • 系统自动管理导航栈

🧪 测试要点

1. 导航功能测试

  • 点击扫描按钮正确导航到 ScannerView
  • 返回按钮正常工作
  • 滑动返回手势正常响应
  • 导航标题正确显示

2. 扫描功能测试

  • 扫描功能正常工作
  • 扫描完成后可以正常返回
  • 权限管理正常工作
  • UI 组件正常显示

3. 界面布局测试

  • 扫描器充分利用屏幕空间
  • 状态栏正常显示
  • 导航栏样式正确
  • 返回按钮位置正确

🚨 注意事项

1. 导航栈管理

  • 确保 ScannerView 正确集成到导航栈中
  • 避免创建多个导航视图
  • 保持导航层级清晰

2. 状态管理

  • 移除不再需要的状态变量
  • 确保扫描状态在返回时正确清理
  • 保持数据流的清晰性

3. 用户体验

  • 保持扫描界面的全屏体验
  • 确保返回操作直观易懂
  • 维持扫描功能的完整性

📊 修改总结

通过这次修改,我们成功地将 ScannerView 从 sheet 模态弹窗改为导航方式,主要变化包括:

  1. ContentView: 使用 NavigationLink 替代 Button + sheet
  2. ScannerView: 添加导航标题,移除 dismiss 逻辑
  3. ScanningOverlayView: 移除关闭按钮和 onClose 参数
  4. 整体体验: 提供更一致、更直观的导航体验

这次修改不仅简化了代码结构,还提升了用户体验,使扫描功能更好地集成到应用的导航系统中。用户现在可以通过标准的导航方式访问扫描器,享受更流畅、更一致的应用体验。