导航与返回的层级模型
别名: 导航栈 · 层级导航 · push pop · 模态呈现
概念解释
苹果平台上的导航层级(navigation hierarchy)把界面之间的关系做成一棵有父有子的树,而不是一张平铺的屏幕清单。「进入下一层」是把子界面压进栈(push),「返回」是回到父界面(pop)。返回不是「撤销刚才那一下」,也不是「关掉随便哪个浮层」,而是沿着父子边往根走。系统导航栏左侧的返回箭头、从左缘滑入的返回手势,都是这棵树的可见出口,不是应用自己画的装饰按钮。
另一类关系是模态呈现(modal presentation):新界面盖在当前树上,形成一个临时根,结束方式是下拉关闭或点取消,而不是 pop。把本该模态的流程做成 push,或把本该进栈的详情做成模态,用户对「我现在在哪一层、出口朝哪」的空间判断会立刻错位。
机制
层级能被预期,是因为系统把「现在在哪」编码进了栈深度,而不是编码进页面标题。栈里有父界面时,导航栏自动出现返回出口,边缘手势也绑定到同一次 pop;栈空了,这两个出口一起消失。出口和结构是同一份数据的两个投影,所以用户不必先读按钮文案再猜「返回会去哪」——去父界面是结构本身给出的答案。
模态不进同一条栈,是因为任务被当成「打断」而不是「更深」。打断需要一条与 pop 可区分的结束手势,否则用户会把下拉关闭和边缘返回当成同一件事,在半页表单上滑出应用或丢掉未提交内容。自定义返回按钮若只改外观、不接到系统栈,边缘手势会失效,标题也不会跟着变成父界面的名字——出口看起来还在,结构已经断了。
边界
分栏、标签栏和多窗口会让「单一栈」不够用:每个栏或每扇窗口可以有自己的栈,返回只作用于当前那一支,不会跨栏跳走。游戏、相机取景这类全屏沉浸界面常常藏起导航栏,此时层级出口必须改由系统提供的关闭或明确的「完成」,不能指望用户还找得到左上角箭头。WebView 和内部浏览器有自己的历史栈,和原生导航栈叠在一起时,谁先响应返回必须事先定死,否则一次滑动会同时 pop 网页和 pop 原生页。从通知或通用链接深链进来的界面可能没有父界面,这时硬造一个返回箭头会把人送进空栈或首页,不如提供「关闭」或「完成」。
怎么落地
- 用系统导航栈表达父子页(列表→详情→编辑),用模态表达打断性任务(新建、筛选、登录),不要混用。
- 保留系统生成的返回出口;若必须自定义左侧按钮,确认边缘返回手势和标题回退仍然绑定在同一次 pop 上。
- 深链落地页没有父界面时,用关闭或完成,而不是画一个指向未知目的地的返回箭头。
- 验证:从首页走到最深一层,只用边缘手势一路返回,记录是否每次都回到结构上的父界面、标题是否同步变化;再对模态页只做下拉关闭,确认不会误 pop 底下的栈。任何一次「返回去了别的分支」或「手势没反应但按钮能点」都说明出口和栈已经脱节。