WWDC Quick Look 💓 By SwiftGGTeam
Design intuitive search experiences

Design intuitive search experiences

观看原视频

Highlight

Apple 在 iOS、iPadOS 和 macOS 上统一了 Search Field 组件,并为不同导航模型(Toolbar、Tab Bar、Sidebar)提供了明确的搜索放置指南,开发者可以直接套用这些模式来降低用户查找内容时的认知负担。

核心内容

搜索是用户打开 App 后的第一站

用户在 Pages 里找文档、在 Apple TV 里找电影、在 Apple Music 里探索新艺人——搜索往往是他们做的第一件事。设计一个糟糕的搜索体验,等于让用户在 App 门口就卡住。

Apple 今年在 Liquid Glass 设计语言下重新梳理了搜索组件的行为规范。Search Field 自动包含四个核心元素:左侧的放大镜图标、Placeholder 提示文字、输入后出现的清除按钮,以及 iOS 上聚焦时显示的 Cancel 按钮。这些元素的位置和交互是固定的,开发者不应该为了「品牌差异化」把它们改掉。

搜索放哪里,取决于两件事

03:41

第一个问题是:用户怎么在你的 App 里导航?第二个问题是:搜索的范围有多大?

这两个问题决定了搜索应该放在 Toolbar、Tab Bar 还是内容区域里。

以 Mail 为例。Mail 的主导航发生在邮件列表里,底部 Toolbar 承载了主要操作。把搜索放在底部 Toolbar 是最符合人体工学的——用户单手就能触达,而且旁边就是其他常用按钮。当搜索获得焦点时,搜索框会自动上移到键盘上方,避免被键盘遮挡。

Stocks App 的情况不同。它的底部被一个 Sheet 占据,没有空间放 Toolbar。这时候搜索放在顶部 Toolbar 是合理的,同样会在聚焦时上移到键盘上方。

Tab Bar 应用:全局搜索 vs 局部搜索

05:22

对于使用 Tab Bar 的 App,Apple 推荐两种搜索 Tab 的形式。

第一种是普通 Tab。点击后进入一个搜索落地页,搜索框在页面顶部,下方可以展示推荐内容或分类。Apple TV 用了这种方式,用户在搜索前先看到各种影视类型,处于一种探索心态。

第二种是 Prominent Tab。点击后立刻拉起键盘进入搜索状态,没有中间页。Phone App 的搜索 Tab 就是这样设计的——用户通常知道要找什么,只想快速回到某个联系人或通话记录。

除了全局搜索 Tab,也可以在特定 Tab 内放置局部搜索。Apple Music 的「资料库」Tab 里,搜索框放在标题下方,Placeholder 文字明确写着「搜索资料库」。这让用户清楚知道搜索范围仅限于自己的音乐收藏,而不是整个 Apple Music 目录。

iPad 和 Mac:三种放置位置

07:47

iPad 和 Mac 的屏幕更宽,导航模型相似,搜索体验应该尽量保持一致。

三种推荐位置:

  • Toolbar 尾部:适合 Split View 应用,比如 Mail。用户在左侧浏览搜索结果,右侧详情视图保持可见。这是 Notes 和 Files 都在用的模式。
  • Sidebar 顶部:适合需要过滤 Sidebar 内导航项的场景。Settings App 的搜索就在 Sidebar 顶部,输入后只显示匹配的设置项。
  • 独立搜索 Tab/Section:适合内容丰富的多分区应用,比如 Apple Music。这种方式提供了更大的空间来展示搜索结果。

Toolbar 上的搜索框会根据空间自动缩放或折叠成按钮。激活后展开到适合输入的宽度,溢出的 Toolbar 项自动收进菜单。

详细内容

利用搜索建议减少输入

10:36

用户打开搜索,往往意味着他们在浏览时没有直接找到目标。这时候应该尽可能减少他们的操作步骤。

最近搜索:在 iOS 上,搜索框获得焦点后直接显示在输入框下方;在 iPad 和 Mac 上,如果搜索框在 Toolbar 或 Sidebar 中,最近搜索以菜单形式呈现;如果有搜索 Tab,则与推荐内容一起展示在页面上。只展示用户实际查看或交互过的结果,并提供删除单个项和清空全部的操作。

预测建议:用户开始输入后,实时显示与输入内容对应的补全建议。建议中的用户已输入部分和预测部分要在视觉上区分开。控制建议数量,让搜索结果始终处于视觉中心。

用 Scope Bar 和 Token 过滤结果

12:38

当搜索结果来自多个位置、类别或账户时,过滤能力就很重要。

Scope Bar:轻量级过滤控件。Mail App 用它切换「所有邮箱」和「当前邮箱」两种搜索范围。这种过滤方式直观,用户一眼就能看到自己在搜哪里。

Search Token:用户输入特定关键词时,Token 以高亮文本形式出现在搜索框内,用户可以持续添加多个 Token 来组合过滤条件。Photos App 里可以组合「Joshua Tree」和「2021」两个 Token,快速定位特定时间和地点的照片。

Token 的缺点是发现性较差,不应该替代可见的过滤 UI。最佳实践是把 Token 和 Scope Bar 或其他过滤控件搭配使用。

无结果时的空状态

14:41

搜索没有返回结果时,不要显示空白页面。Apple 提供了 Content Unavailable View,配置为搜索模式后会自动显示搜索图标、标题和副标题。建议在空状态中显示用户当前的搜索文本,帮助他们快速发现拼写错误。

SwiftUI 中的搜索实现

虽然没有提供具体的代码片段,但从 session 描述和平台规范可以推断出实现方向。

在 SwiftUI 中,搜索框通过 .searchable 修饰符添加:

// Toolbar 搜索(iOS 底部或 iPad/Mac 顶部)
ContentView()
    .searchable(text: $searchText, placement: .navigationBarDrawer)

// 带 Scope Bar 的搜索
ContentView()
    .searchable(text: $searchText)
    .searchScopes($searchScope) {
        Text("All Mailboxes").tag(Mailbox.all)
        Text("Current Mailbox").tag(Mailbox.current)
    }

// 带 Token 的搜索
ContentView()
    .searchable(text: $searchText, tokens: $searchTokens) { token in
        Text(token.name)
    }

关键点:

  • .searchable 自动处理搜索框的样式、清除按钮和 Cancel 按钮
  • placement 参数控制搜索框位置,系统会根据平台和上下文自动选择最佳呈现方式
  • .searchScopes 添加 Scope Bar,用户点击即可切换搜索范围
  • Token 通过 tokens 参数绑定,用户在输入特定关键词时系统自动生成 Token
  • 搜索建议通过 .searchSuggestions 修饰符提供,支持最近搜索和预测补全

核心启发

  1. 把搜索从顶部移到底部 Toolbar

    • 做什么:将 iOS App 的搜索框从导航栏移到底部 Toolbar
    • 为什么:单手操作更自然,聚焦时自动上移到键盘上方,不会遮挡内容
    • 怎么开始:在 SwiftUI 中使用 .searchable(placement: .toolbar),UIKit 中使用 UISearchController 配合底部 Toolbar
  2. 为 Tab Bar 应用添加 Prominent Search Tab

    • 做什么:把搜索做成一个独立的 Tab,点击立刻进入搜索状态
    • 为什么:用户不需要先进入某个页面再搜索,全局内容始终只有一个点击的距离
    • 怎么开始:在 TabView 中配置一个以搜索为图标的 Tab,页面加载时自动聚焦搜索框
  3. 用最近搜索降低重复输入

    • 做什么:记录用户实际点击过的搜索结果,在搜索框聚焦时展示
    • 为什么:很多搜索是重复行为,用户想回到之前看过的内容
    • 怎么开始:用 UserDefaults 或 Core Data 存储最近搜索记录,通过 .searchSuggestions 展示
  4. 用 Token 实现自然语言过滤

    • 做什么:让用户输入「2021 年 Joshua Tree 的照片」时,自动提取「2021」和「Joshua Tree」作为过滤 Token
    • 为什么:比传统的筛选器更灵活,用户可以组合任意条件
    • 怎么开始:实现 token 初始化器,监听搜索文本变化,匹配预设关键词后生成 Token
  5. 为无结果设计有意义的空状态

    • 做什么:搜索无结果时显示当前搜索词,并给出操作建议
    • 为什么:空白页面让用户不确定是网络问题还是真的没有结果
    • 怎么开始:使用 ContentUnavailableView.search(text: searchText),自动获得标准搜索空状态

关联 Session

评论

GitHub Issues · utterances