|
|
|
@ -0,0 +1,246 @@
|
|
|
|
|
# ScannerView 导航方式修改说明
|
|
|
|
|
|
|
|
|
|
## 🎯 修改目标
|
|
|
|
|
|
|
|
|
|
将 `ScannerView` 的展示方式从 `sheet` 模态弹窗改为 `NavigationLink` 导航方式,提供更好的用户体验和导航一致性。
|
|
|
|
|
|
|
|
|
|
## 🔄 主要修改内容
|
|
|
|
|
|
|
|
|
|
### 1. **ContentView.swift 的修改**
|
|
|
|
|
|
|
|
|
|
#### 移除的状态变量
|
|
|
|
|
```swift
|
|
|
|
|
// 移除
|
|
|
|
|
@State private var showScanner = false
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### 修改扫描按钮
|
|
|
|
|
```swift
|
|
|
|
|
// 修改前:使用 Button + sheet
|
|
|
|
|
Button(action: {
|
|
|
|
|
showScanner = true
|
|
|
|
|
}) {
|
|
|
|
|
// 按钮内容
|
|
|
|
|
}
|
|
|
|
|
.sheet(isPresented: $showScanner) {
|
|
|
|
|
ScannerView()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 修改后:使用 NavigationLink
|
|
|
|
|
NavigationLink(destination: ScannerView()) {
|
|
|
|
|
// 按钮内容
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### 移除 sheet 修饰符
|
|
|
|
|
```swift
|
|
|
|
|
// 移除
|
|
|
|
|
.sheet(isPresented: $showScanner) {
|
|
|
|
|
ScannerView()
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 2. **ScannerView.swift 的修改**
|
|
|
|
|
|
|
|
|
|
#### 移除环境变量
|
|
|
|
|
```swift
|
|
|
|
|
// 移除
|
|
|
|
|
@Environment(\.dismiss) private var dismiss
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### 添加导航标题和样式
|
|
|
|
|
```swift
|
|
|
|
|
.navigationTitle("扫描器")
|
|
|
|
|
.navigationBarTitleDisplayMode(.inline)
|
|
|
|
|
.navigationBarBackButtonHidden(false)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### 修改关闭逻辑
|
|
|
|
|
```swift
|
|
|
|
|
// 修改前
|
|
|
|
|
onClose: { dismiss() }
|
|
|
|
|
|
|
|
|
|
// 修改后
|
|
|
|
|
onClose: { /* 导航会自动返回 */ }
|
|
|
|
|
|
|
|
|
|
// 修改前
|
|
|
|
|
dismiss()
|
|
|
|
|
|
|
|
|
|
// 修改后
|
|
|
|
|
// 使用导航返回,不需要手动dismiss
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### 更新预览
|
|
|
|
|
```swift
|
|
|
|
|
#if DEBUG
|
|
|
|
|
struct ScannerView_Previews: PreviewProvider {
|
|
|
|
|
static var previews: some View {
|
|
|
|
|
NavigationView {
|
|
|
|
|
ScannerView()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 3. **ScanningOverlayView.swift 的修改**
|
|
|
|
|
|
|
|
|
|
#### 移除 onClose 参数
|
|
|
|
|
```swift
|
|
|
|
|
// 修改前
|
|
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### 移除关闭按钮
|
|
|
|
|
```swift
|
|
|
|
|
// 修改前
|
|
|
|
|
if !showPreviewPause {
|
|
|
|
|
Button("close_button".localized) {
|
|
|
|
|
onClose()
|
|
|
|
|
}
|
|
|
|
|
// 按钮样式
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 修改后
|
|
|
|
|
// 移除关闭按钮,因为现在使用导航返回
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### 更新调用方式
|
|
|
|
|
```swift
|
|
|
|
|
// 修改前
|
|
|
|
|
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 方式)
|
|
|
|
|
- 集成到导航栈中
|
|
|
|
|
- 自动显示返回按钮
|
|
|
|
|
- 支持滑动返回手势
|
|
|
|
|
- 保持状态栏显示
|
|
|
|
|
- 显示导航标题
|
|
|
|
|
|
|
|
|
|
## 🔧 技术实现细节
|
|
|
|
|
|
|
|
|
|
### 1. **NavigationLink 的使用**
|
|
|
|
|
```swift
|
|
|
|
|
NavigationLink(destination: ScannerView()) {
|
|
|
|
|
HStack {
|
|
|
|
|
Image(systemName: "camera.fill")
|
|
|
|
|
Text("start_scanning".localized)
|
|
|
|
|
}
|
|
|
|
|
// 按钮样式
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 2. **导航标题设置**
|
|
|
|
|
```swift
|
|
|
|
|
.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. **整体体验**: 提供更一致、更直观的导航体验
|
|
|
|
|
|
|
|
|
|
这次修改不仅简化了代码结构,还提升了用户体验,使扫描功能更好地集成到应用的导航系统中。用户现在可以通过标准的导航方式访问扫描器,享受更流畅、更一致的应用体验。
|