别让筛选页一上来太长:用 AI + SwiftUI DisclosureGroup 折叠高级选项

别让筛选页一上来太长:用 AI + SwiftUI DisclosureGroup 折叠高级选项

这一技教你让 AI 用 SwiftUI DisclosureGroup 把低频筛选收进可展开区域,并用 Xcode 验收筛选状态、窄屏、大字号和 VoiceOver。

高级筛选不该占满首屏

一打开筛选页,用户先看到十几个选项,真正常用的日期、状态和关键词反而被推到下面。可以把低频条件放进 SwiftUI 的 DisclosureGroup:首屏只露出常用筛选,用户需要时再展开高级选项。Apple 对它的定义就是根据展开控件的状态显示或隐藏另一组内容。1
这招解决的是信息顺序,不是把筛选项删掉。产品经理可以先定哪些条件默认可见,再让 AI 只改筛选区的容器,不碰查询、分页和结果排序。

先写清楚哪些选项该折叠

不要直接对 AI 说「把筛选页做得简洁一点」。先把筛选条件分成两组:
  • 常用条件:用户大多数时候会先用,或者不选它就很难开始筛选,例如关键词、日期、状态。
  • 高级条件:能缩小结果范围,但使用频率较低,例如多个标签组合、来源、负责人或排序方式。
再补三条产品规则:
  1. 页面第一次打开时,高级条件默认收起,常用条件仍然可以直接操作。
  2. 展开后,用户能看到每个高级条件的当前值;收起只是隐藏内容,不应悄悄清掉已选条件。
  3. 用户点「应用筛选」后,结果页要能看出高级条件仍然生效;重新进入筛选页时,是否保持展开由产品决定,不让 AI 自己猜。
如果高级条件会影响结果数量,可以在收起状态显示一个轻量提示,例如「已选 2 个高级条件」。这比让用户重新展开、逐项检查更稳妥。

把现有筛选区交给 AI

在 Xcode 中找到筛选页面,先确认当前筛选值放在哪里。把筛选 View、状态变量和「应用筛选」动作一起提供给 AI。不要只贴一个空的 VStack,否则它可能生成一套看起来能展开、实际没有接上查询条件的演示代码。
可以直接使用这段指令:
请只改造当前 SwiftUI 筛选页面的布局,不要改筛选请求、分页、结果排序、网络层和现有筛选值的含义。
请把关键词、日期和状态保留在默认可见区域,把标签、来源和负责人放进一个标题为「高级筛选」的 DisclosureGroup。页面首次进入时默认收起。收起或展开不能清空已经选择的高级条件;「应用筛选」仍要读取同一份筛选状态。
请优先使用 DisclosureGroup(isExpanded:content:label:),让 isExpanded 绑定一个明确的展开状态。先指出当前项目的 Deployment Target 和 SwiftUI SDK 是否支持当前写法;如果代码结构不适合,请先说明需要保留的状态和最小改动范围。最后列出窄屏、大字号、VoiceOver、重新进入页面和已有高级条件这几个验收场景。
这段指令把改动边界写死了。AI 的任务是换一个容器,不是顺手重写筛选逻辑。

看懂最小改动

如果现有筛选值已经由页面状态管理,结构可以接近下面这样:
@State private var showAdvancedFilters = false

var body: some View {
    Form {
        Section("常用筛选") {
            // 现有的关键词、日期和状态控件
        }

Section {
            DisclosureGroup(
                isExpanded: $showAdvancedFilters
            ) {
                // 现有的标签、来源和负责人控件
            } label: {
                Text("高级筛选")
            }
        }

Button("应用筛选") {
            applyFilters()
        }
    }
}
Apple 的这个初始化方法会接收一个展开状态的绑定,绑定值表示当前内容是展开还是收起。2 这里的 showAdvancedFilters 只描述界面是否展开,不应该被误用成「是否启用高级筛选」或「是否提交筛选」的业务状态。
检查 AI 改动时,重点看四件事:
  • 高级控件是不是仍然绑定原来的筛选值,而不是在 DisclosureGroup 里重新造一份临时状态。
  • applyFilters() 是否仍然读取完整筛选条件,而不是只读取默认可见的那一组。
  • 页面首次创建时是否确实收起,产品要求保持展开时,是否有明确的状态来源。
  • 展开状态改变时,是否触发了不必要的网络请求、清空结果或重置分页。
如果要在标题旁显示「已选 2 个高级条件」,让 AI 先把计数规则写出来:空值不计数,默认值是否计数,互斥选项如何计算。不要让它用字符串是否为空来猜所有控件的状态。

用 Xcode 验收折叠后的真实体验

不要只点一次箭头确认内容会出现。用固定的测试数据和几组已选条件,按下面顺序检查:
  1. 第一次打开页面,确认关键词、日期和状态可见,高级条件收起,用户知道还有一组可选条件。
  2. 展开高级筛选,确认标签、来源和负责人都能操作,且没有被键盘、底部按钮或分组标题遮住。
  3. 选中一个高级条件后收起,再展开,确认选择仍在;如果产品规则允许收起即清空,也要有明确的清除反馈,不能静默发生。
  4. 先选常用条件,再选高级条件,点击「应用筛选」,确认结果同时使用两组条件。
  5. 直接进入结果页,再返回筛选页,测试高级条件是否保留、展开状态是否符合产品规则;不要把「返回后保持」当成 DisclosureGroup 自动提供的能力。
  6. 在窄屏 iPhone 上测试长标题和长筛选值,确认展开后的内容不会横向截断,应用按钮仍然可见。
  7. 打开大字号,确认「高级筛选」标题、选中状态和控件标签都能读完;如果布局需要滚动,滚动顺序要自然。
  8. 用 VoiceOver 从常用筛选移动到高级筛选,再展开并操作一个条件,确认用户能知道这个控件的作用和当前展开状态。
  9. 连续展开、收起,再快速点击「应用筛选」,确认不会因为动画或状态变化提交两次请求。
这里有一个容易漏掉的产品问题:如果用户选了高级条件,页面收起后看起来和「没有高级条件」完全一样,下一次回来很容易误判。可以把已选条件数量放在标题旁,也可以让收起状态显示一行简短摘要,具体选哪种取决于页面空间和文案长度。

这招的边界

DisclosureGroup 只负责一组内容的显示与隐藏。它不会替你决定哪些筛选条件重要,也不会自动保存筛选值、合并请求、处理分页或更新结果。那些责任仍然属于现有状态和业务流程。
也不要把所有内容都塞进高级筛选。用户完成核心任务必须依赖的条件应该留在首屏;危险操作、权限提示和错误信息也不应藏在一个默认收起的区域里。折叠是降低首屏负担,不是把关键反馈藏起来。
如果项目的最低系统版本或当前 SDK 不支持 AI 给出的写法,以 Xcode 的编译结果为准。先让 AI 说明可用 API 和兼容改法,再决定是否调整项目版本,不要凭记忆填写版本号。

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

  • 列出当前筛选页全部条件,并标出用户最常用的几项。
  • 定义高级条件首次进入时的展开状态,以及返回页面后的保留规则。
  • 写明收起后已选条件是否保留,以及如何给用户提示。
  • 把筛选 View、状态变量和应用动作一起交给 AI。
  • 要求 AI 只替换筛选区布局,不改请求、分页和排序。
  • 检查 DisclosureGroup 内的控件是否仍绑定原有筛选状态。
  • 用已选条件测试展开、收起、应用和返回流程。
  • 在窄屏、大字号和 VoiceOver 下各验收一次。
  • 快速重复操作,确认展开状态不会触发重复请求或清空结果。
先拿一个已有筛选页做改造,不要同时重做结果卡片。只要用户能先用常用条件开始筛选,又能在需要时找到完整选项,这次布局调整就达到了目的。

Related content

  • Sign in to comment.
More from this channel