最近在一些 iOS 相关视频的弹幕/评论中,我注意到有很多安卓用户对于 iOS 的侧滑返回手势有着不小的怨念,甚至不惜以“反人类”这种词汇去形容 iOS 的返回操作。诚然,随着现在 iPhone 的屏幕尺寸越来越大,屏幕的宽度自然也是水涨船高。作为一名 iOS 开发者,我并不认为 iOS 的默认返回行为毫无问题,同样的,也不赞同应该去“抄安卓作业”这种论调。让我们先来看看被安卓用户认为是“教科书”的安卓交互是怎样的。

现代安卓的返回交互

之所以说是现代安卓,是因为早期的安卓从最开始的实体“四大金刚”按键,到后来的屏幕底部虚拟按键,始终都是有一个“返回”按键存在的。随着全面屏概念的流行,现如今国内大多数安卓手机都不再提供底部按钮,至少是不默认提供,而是改为使用一种名为“全面屏手势”的全局系统手势。

54ba0e7463e1a35d148a839ce2c5c19cd25748094f122-ctGsLT_fw1200

其中回到桌面、多任务切换大体上与如今的无 Home 键 iOS 交互一致,然而本文讨论的重点,“返回”操作,却有着看似相同,本质却截然不同的交互。说它们相同,是说从手势上都是从屏幕边缘向中心滑动(安卓两侧均可,iOS 只有固定的一侧),说它们不同,是说“返回“这个概念在两个系统中完全无法对应。

先说说安卓的返回,过去的安卓是存在实体的返回按钮的,如今的安卓使用全局的边缘滑动手势,本质上二者是一回事,都是系统告知当前应用,应用告知当前页面,“返回”事件被触发,页面执行对应操作。可以说由于历史的惯性,安卓的每个页面都是可以响应一个明确的名为“返回”的事件的。

然而从 iPhone 诞生之初,整个设备上的实体按键数量就要更少。除了音量+/-按键,静音切换按键,电源键之外就只剩下了最常用的 Home 键。在多数情况下,按下这几个按键的事件都不需要应用去处理,至少是不需要每一个页面去处理。因此站在 iOS 的每个页面的视角看,可以认为不存在自身无法感知的退出事件的存在,或者说任何页面退出操作的起始点都是自身。

为什么不抄安卓的作业

然而说了这么多,却还是没有说清楚 iOS 为什么不能提供类似安卓的返回手势。对于这个问题,个人认为有两点原因。

iOS 在坚持什么

首先,我认为苹果要保证 iOS 的易用性,手段就是让手指在屏幕上的操作尽可能贴近现实,具体到我们的问题上,页面跟随手指的滑动不会发生偏移。

如果认真观察 iOS 的交互细节就会发现,当你的手指按住屏幕开始滑动时,不管你滑动的过程如何,手指点击位置的内容不会发生变化。举个例子,当你点击某个 tableView 中 cell 的位置开始滑动时,结束滑动时那个 cell 仍然会在你的手指位置,只是 tableView 整体发生了偏移,即使当你滑动到边界位置不能继续滑动时仍然如此。NavigationView 的侧滑返回仍然遵循这个原则,滑动过程中页面始终与手指保持相对位置不变,甚至你在滑动过程中后悔,当你滑回到初始位置时,要退出的页面也会回到退出前状态。

然而如果在 iOS 上使用类似安卓的交互,侧滑手势的偏移量到达一定阈值触发返回,则手指按下-侧滑-抬起手指的整个过程并无页面位置的改变作为响应,只在操作过程结束时页面消失,这违背了 iOS 的设计原则,更不用说会出现从右侧屏幕边缘开始的侧滑操作页面,消失动画从左往右这种奇怪交互。

安卓的设计并非无懈可击

举一个我从视频里看到的例子:

设想你在使用推特 App,当你:

  1. 打开推文1
  2. 切换到桌面,打开浏览器搜索某个内容
  3. 点击搜索结果中的某条推文
  4. 系统跳转回推特 App,自动打开推文2
  5. 此时触发返回手势

效果是:1. 返回到推文1,还是 2. 跳转回浏览器?

这个例子说明了一个问题:应用内页面之间也许可能维持线性的前后关系,但随着应用间跳转的出现,按下“返回”按钮可能的效果可能未必符合用户的预期。

iOS 如何处理这种情况

如果把同样的操作在 iOS 上重复一次,会发现 iOS 针对不同的返回路径提供的不同的入口:位于状态栏左上角的用于返回上一个App的按钮,以及侧滑返回上一个页面。

这样的处理给了用户明确的预期:在 App 内的任何返回操作都只会影响 App 内的页面,不会在 App 间跳转。能在 App 间跳转的入口都不会放在 App 内,例如放在状态栏上。

iOS 的返回是指什么

当我们抛开现状,设想一下如果在 iOS 上增加全局的返回事件,应当处理以下几种情况:

  • 应用间跳转的返回
  • 对于 present 场景的 dismiss
  • 对于 NavigationView 的 pop
  • 其他开发者自定义的场景

基于 iOS 的设计规范,如果不能提供与交互和动画协调统一的手势操作,想必系统是不可能提供固定位置的返回手势用于覆盖上述的诸多情况。

开发者能做什么

既然苹果官方不大可能提供系统级的解决方案,而这里又确实给许多用户带来了不便,其本质原因在于屏幕面积的扩大导致的用户手指触及范围的相对减小。作为 iOS 开发者能在开发过程中做些什么呢?以下是我的几点个人建议:

修复所有 NavigationView 相关的侧滑返回手势

就我观察到的一些 App 来说,很多都是明明使用了 UINavigationController 却无法侧滑返回,推测可能的原因有以下几点:

  • 误关闭/代码bug/手势冲突等原因导致默认侧滑手势失效,建议对症修复
  • 页面涉及到用户输入内容,设计时刻意在该页面关闭了手势识别。按照苹果的设计规范来说用户输入的页面应当使用模态窗口,而不是基于 NavigationView 做 push,建议调整交互形式
  • 使用了错误的方式隐藏 navigationBar。使用 navigationController.isNavigationBarHidden 属性隐藏 navigationBar 会导致侧滑返回手势失效,使用 navigationController.navigationBar.isHidden 则不会。

对于 present 场景,非必要场景不使用 .fullScreen

从 iOS 13 开始,系统的默认 present 样式从原来的 .fullScreen 变成了 .automatic, .automatic 样式在最常见的竖屏 iPhone 对应的 size class 下实际上是 .pageSheet

由于全面屏设备的覆盖率逐渐上升,.fullScreen 风格的优势越来越少,实测在 iPhone 13 mini 机型上可用高度只增加了 22 points,在更大尺寸的机型上可用高度的差距只会更小。而在非 .fullScreen 风格下系统提供了默认的下拉 dismiss 手势,使得用户无需点击屏幕顶部的取消按钮即可关闭当前页面。

此外,在 iOS 15 上,对于无需占满全屏幕的场景,系统还提供了 sheetPresentationController 以更直观的方式呈现内容。这些都是使用原始的 .fullScreen 无法享受到的便利。

注意转场动画的形式

一种常见的容易误导用户的错误是,在非 push 的场景下使用类似于 push 的从右到左的动画,这样会让用户误认为可以从左侧滑动返回。即使出于各种原因无法支持侧滑返回,也可以通过展现时的动画给予用户暗示。

左上角图标不要不分场合使用向左的箭头

另一种常见的误导是无论什么页面左上角的按钮都是向左的箭头。iOS 的默认行为中,只有在能侧滑返回页面的 NavigationBar 上才会展示向左箭头,用户在看到箭头时会下意识认为可以侧滑返回,如果不能的话会给用户带来不小的挫败感。建议使用“❌”按钮或是“取消”之类的文字作为替代。

考虑适配非边缘的滑动返回手势

许多国外的主流 App (Twitter、Instagram等)以及部分国内 App (部分字节系)已经适配了非边缘的滑动返回手势。这种处理方式一方面不需要用户费力触及屏幕边缘,另一方面也不违背上述苹果的交互原则,相对来说是一种比较合理的解决方案。

关于如何类似效果的具体实现,详见下篇 (续)如何实现非边缘侧滑返回手势?