别让工具栏塞满按钮:用 AI + SwiftUI Menu 收好次要操作

别让工具栏塞满按钮:用 AI + SwiftUI Menu 收好次要操作

这一技教你先把主动作与低频动作分层,再让 AI 用 SwiftUI Menu 收好次要操作,并在 Xcode 独立验收危险操作、VoiceOver、大字号与重复点击。

一个页面为什么会塞满按钮

列表行、详情页和导航栏经常同时放着分享、复制、收藏、标记、归档、删除。每个动作单看都有道理,合在一屏就变成一排难读的小图标,用户还得猜每个图标的意思。
SwiftUI 的 Menu 是一个「点击后展示一组操作」的控件。Apple 对它的定义就是用于呈现操作菜单;Human Interface Guidelines 也把菜单描述为一种节省空间、在交互后才展示选项的方式。1 2
这招适合收纳低频、同属一个对象的次要动作。主动作仍然应该直接放在页面上,比如「发送」或「保存」;用户偶尔才用的「复制链接」「标记未读」「归档」,可以放进「更多操作」。这样不是把功能藏起来,而是把最常用的动作和备用动作分开。

先做一张动作分层表

让 AI 改代码前,先拿一个真实页面整理动作。不要从「把按钮变少」开始,而要先决定哪些动作应该直接出现。
动作类型建议位置PM 要确认的规则
完成当前任务的主动作页面上的直接按钮用户是否一眼就能找到
偶尔使用的辅助动作「更多操作」菜单菜单项名称是否能独立看懂
会改变当前选择的动作菜单或选择控件选择后页面是否立即更新
删除、清空、放弃编辑菜单项触发确认流程是否保留确认、撤销或恢复入口
菜单的价值是减少同时可见的控件,不是替产品删掉动作。删除和清空这类高风险操作,放进菜单后仍然要走确认流程,不能因为多了一层菜单就直接执行。

把现有操作交给 AI

在 Xcode 里找到当前页面的操作区域,把这三类上下文一起交给 AI:
  • 这组操作属于哪个对象,例如一条消息、一张订单或一份草稿。
  • 哪个动作是主动作,哪些动作低频但仍要保留。
  • 每个动作现在调用的函数,以及删除、失败和完成后的反馈。
可以直接这样下指令:
请只整理当前 SwiftUI 页面里的次要操作,不要改数据模型、网络请求和页面导航。先根据动作频率和风险,把操作分成直接按钮与「更多操作」菜单两组。
保留现有的 action 函数和成功、失败处理。用一个清楚的 Menu 承载低频操作,菜单按钮的文字要能脱离图标独立理解;保留当前页面的主动作。删除、清空和放弃编辑不能直接执行,要继续进入现有确认流程。
请先列出你准备移动的操作和理由,再给出最小改动代码。最后列出 Xcode 验收步骤,并检查窄屏、大字号、深色模式和 VoiceOver。
这个提示词限制了改动范围,也让 AI 先解释动作分层。SwiftUI 的 Menu 可以承载操作项,Apple 的相关示例也把菜单用于组织 commands、actions 或 items。3 菜单里的具体动作仍然应该由 Button 触发,因为 Button 的职责就是启动一个动作。4

用最小代码接上菜单

假设页面已经有 copyLink()markUnread()requestDeleteConfirmation() 三个动作,AI 可以把低频操作集中到一个菜单里:
Menu {
    Button("复制链接") {
        copyLink()
    }

Button("标记为未读") {
        markUnread()
    }

Button("删除") {
        requestDeleteConfirmation()
    }
} label: {
    Label("更多操作", systemImage: "ellipsis.circle")
}
这里有三个检查点。
第一,菜单标签不能只剩一个没有解释的省略号。视觉上可以用省略号图标,但要让用户和 VoiceOver 知道这是「更多操作」,而不是一个没有语义的装饰图标。
第二,菜单项写动作,不写实现细节。「复制链接」比「执行复制逻辑」更适合放在用户面前。Apple 的 Button 文档把按钮看作发起动作的控件,所以菜单项的文字应该说明用户点下去会发生什么,而不是暴露函数名。4
第三,删除项只负责进入现有确认流程。不要让 AI 把 requestDeleteConfirmation() 换成直接删除,也不要顺手重写网络请求。菜单只是入口位置变化,业务风险没有消失。
如果菜单中出现的不是「执行一个动作」,而是「从多个值里选一个」,先让 AI 判断是否应该使用选择控件。比如排序方式、显示范围和筛选条件,选中后还要在按钮上保留当前值,否则用户重新打开页面时会不知道自己选了什么。

在 Xcode 里按操作结果验收

运行模拟器或真机,不要只检查菜单能不能弹出来。按这组场景逐项走:
  1. 打开方式:点「更多操作」后菜单稳定出现,第一次点击不会误触任何菜单项;点击菜单外区域可以退出。
  2. 动作完整:逐个点复制、标记、归档等操作,确认原来的成功反馈、失败提示和列表更新仍然存在。
  3. 主动作不被稀释:用户完成页面主要任务时,不需要先打开菜单;主按钮仍然在原来的显眼位置。
  4. 危险操作:点击删除或清空后先出现现有确认界面,取消不会改变数据,确认后才执行删除;失败时仍能看到重试或恢复入口。
  5. 重复点击:慢请求期间反复打开菜单或重复点同一项,确认原有的防重复提交规则仍然有效。Menu 不会替你处理请求幂等。
  6. 窄屏与大字号:把模拟器切到窄屏并打开更大的文字,检查菜单项文字没有被截断,菜单标签也没有挤掉主按钮。
  7. VoiceOver:确认焦点先读出「更多操作」,再读出每个菜单项的完整名称;不要让用户只能根据省略号猜功能。
  8. 状态更新:完成一个菜单操作后,回到页面检查按钮、列表行和提示文案是否同步更新,而不是只有菜单关掉了。
Menu 解决的是操作入口的排列问题。它不会自动替你决定动作优先级,也不会补齐成功、失败、确认、读屏和服务端去重。若一个动作用户必须频繁寻找,或者没有菜单也无法理解它属于哪个对象,就先别急着收进去。

PM 今天可以独立完成的清单

  • 选一个按钮已经拥挤的列表或详情页。
  • 写出主动作、低频辅助动作和高风险动作三类清单。
  • 确认菜单标签要表达「更多操作」,不要只留下无语义的图标。
  • 找到每个现有动作对应的函数、成功反馈、失败处理和确认流程。
  • 让 AI 只改操作区域,先给分层理由,再生成最小 Menu 代码。
  • 检查菜单项文字是否能脱离图标独立理解。
  • 在复制、标记、归档和删除等真实动作上跑一遍成功与失败路径。
  • 验收慢请求、重复点击、窄屏、大字号、深色模式和 VoiceOver。
先收一个页面里的低频动作,确认用户找得到、点得对、结果看得见,再考虑把同样的规则复制到其他页面。

Related content

  • Sign in to comment.
More from this channel