5.1 KiB
5.1 KiB
完成页迭代方案 — 审查报告(禁止应用)
审查对象:左滑进完成页、右滑回最后一节;无顶部返回;无打字机金句;底部「回到我的内容」回到技能页 Tab。
结论:只做审查与完整代码输出,不修改仓库文件。
一、需求与方案对照
| 需求 | 方案 | 审查结论 |
|---|---|---|
| 不想要点开页面导航栏的返回按钮 | 移除顶部导航栏和返回按钮,仅顶部留白 | ✅ 一致 |
| 右滑回到最后一个小节 | .enableSwipeBack() + SwipeBackEnabler 强制开启侧滑返回 |
⚠️ 见下文「侧滑返回」 |
| 最后小节左滑进完成页,右滑回最后小节 | 播放器最后一节挂 LastPageSwipeModifier 左滑 push;完成页右滑 = 系统 pop |
✅ 一致 |
| 不要打字机金句 | 移除打字机区域 | ✅ 一致 |
| 底部「回到我的内容」回到技能页 Tab | 方案写的是 navigationPath = NavigationPath() |
❌ 逻辑错误,见下 |
二、关键问题:底部按钮语义
需求:底部「回到我的内容」要回到技能页 Tab(即技能 Tab 根:课程列表)。
方案中的实现:handleReturnToRoot() 里写的是 navigationPath = NavigationPath(),即清空当前传入的 path。
- 若从技能 Tab进入:传的是
growthPath,清空后 = 技能 Tab 根 ✅ - 若从发现 Tab进入:传的是
homePath,清空后 = 发现 Tab 根,不会切到技能 Tab ❌ - 若从我的 Tab进入:传的是
profilePath,清空后 = 我的 Tab 根,不会切到技能 Tab ❌
因此:仅清空当前 path 无法满足「无论从哪个 Tab 进,都回到技能页 Tab」。
正确做法:底部按钮应调用 navStore.switchToGrowthTab()(切到技能 Tab + 清空 growthPath),与当前线上 CompletionView 的「继续学习」一致。
- CompletionView 需保留
@EnvironmentObject var navStore - 不需要为「回到我的内容」传入
@Binding var navigationPath(调用方无需改传参)
完整代码中已按此修正:底部按钮调用 navStore.switchToGrowthTab(),不传 navigationPath。
三、侧滑返回(SwipeBackEnabler)
- 方案用
SwipeBackEnabler(UIViewControllerRepresentable)在.background里查找navigationController并打开interactivePopGestureRecognizer,以在隐藏导航栏时恢复右滑返回。 - 风险:
makeUIViewController返回的是一颗裸UIViewController(),其navigationController在部分时机可能仍为 nil(例如尚未挂到 NavigationStack 上),DispatchQueue.main.async能缓解但无法完全保证。若遇真机偶发无效,可考虑:- 在
updateUIViewController中轮询/延迟再取一次navigationController,或 - 使用
UINavigationController子类 / 注入方式保证拿到的必为当前栈。
- 在
- 结论:实现可保留,建议在真机多场景(从三个 Tab 进入完成页后右滑)验证;若失效再加强时机或注入方式。
四、VerticalScreenPlayerView 与占位页
- 方案采用「不使用占位页,仅最后一节左滑手势 push 完成页」:TabView 只渲染
ForEach(allCourseNodes),不再多一页CompletionPlaceholderPage。 - 影响:
- 进入完成页仅剩「在最后一节左滑」这一种方式;「滑到下一空白页再进完成页」的路径被移除。
- 从完成页右滑或 dismiss 后,播放器不再存在「当前是占位页、需在 onAppear 里切回最后一节」的状态,可删除
onAppear里对currentNodeId == "wg://completion"的处理。
- 与现有调用方:NoteTreeView / NoteListView 不传
navigationPath,triggerCompletionNavigation里需guard let path = navigationPath else { return },从笔记进的播放器仍不会 push 完成页,行为不变。
五、CompletionView 视觉与接口
- 视觉:从当前 3D 翻转卡片 + 打字机,改为「赛博印章」:圆环 + 未盖章「完」/ 盖章后「已完成的第 N 节」+ 底部「回到我的内容」。
- 接口:
- 保留:
courseId,courseTitle,completedLessonCount。 - 不增加
@Binding var navigationPath(底部用navStore.switchToGrowthTab())。 - 保留
@EnvironmentObject var navStore。
- 保留:
- 调用方:GrowthView / ProfileView / DiscoveryView 的
.completion分支无需新增参数,仍为三参构造。
六、审查结论汇总
| 项 | 结论 |
|---|---|
| 顶部去掉返回按钮 | ✅ 方案正确 |
| 右滑回最后一节 | ✅ 思路正确;SwipeBackEnabler 需真机验证,偶发需加强时机 |
| 最后小节左滑进完成页 | ✅ 保留 LastPageSwipeModifier 即可 |
| 去掉打字机金句 | ✅ 方案正确 |
| 底部回到技能页 Tab | ❌ 方案用「清空当前 path」会错;应用 navStore.switchToGrowthTab(),完整代码已改 |
| 调用方改动 | ✅ CompletionView 不需新参数;VerticalScreenPlayerView 保持可选 navigationPath,笔记流不受影响 |
完整代码见下(仅作交付,不写入仓库)。