
别让日期输入靠猜:用 AI + SwiftUI DatePicker 限定合法日期范围
这一技教你先把日期含义、合法范围和提交时机写成规则,再让 AI 用 SwiftUI DatePicker 替换手输日期,并在 Xcode 独立验收边界、取消、失败和无障碍。
日期字段的问题,不只是格式
生日、预约日、截止日看起来都能用一个输入框解决,实际却是三套不同规则。用户可能输入一个不存在的日期,也可能选到业务不接受的过去或未来日期;等提交失败后,才发现产品真正需要的是「只能选哪一段时间」。
SwiftUI 的
DatePicker 是用于选择绝对日期的控件。Apple 同时提供了两类常用初始化方式:不带范围时,日期选择是无边界的;带 in: 时,可以把可选日期限制在一个闭区间内。1 2 3PM 不需要先决定控件长什么样。先决定日期的含义、可选范围和提交时机,AI 才能把一个看似简单的字段做对。
先写日期规则表
在打开 Xcode 之前,给当前页面写一张小表。它比「请把日期选择器做得好看」更能约束 AI 的改动。
| 字段场景 | 日期的含义 | 可选范围 | 默认值 | 提交规则 |
|---|---|---|---|---|
| 预约日期 | 用户要到店的日期 | 今天到未来 30 天 | 今天 | 选中后随表单提交 |
| 生日 | 用户的出生日期 | 1900 年 1 月 1 日到今天 | 已保存生日,首次为空 | 空值要提示,不能自动填今天 |
| 任务截止日 | 任务允许完成的最后日期 | 今天到项目结束日 | 产品预设日期 | 超出项目结束日要阻止提交 |
| 预约时间 | 到店的具体时刻 | 营业时间内 | 下一个可预约时段 | 要明确门店所在地或时区 |
这张表里有两个容易漏掉的决定:
- 范围两端是否包含:例如「今天到未来 30 天」是否允许刚好第 30 天。
- 选择是否立即生效:如果日期在弹层里选择后还要点「确定」,就不要把暂存值直接绑定到已经保存的业务值。否则用户点「取消」,页面可能已经被改了。
如果业务确实接受任何日期,可以使用无边界初始化方式;只要存在上下限,就把范围写进规则,不要等提交时才用一条错误文案补救。
让 AI 只改日期字段
在 Xcode 里找到包含日期字段的页面,先保存当前版本。然后把规则表和下面的指令一起交给 AI 编码工具:
请只修改当前 SwiftUI 页面里的日期输入区域,不要重写表单、网络请求、数据模型或提交流程。先根据这张规则实现日期选择:日期含义是「预约日期」;可选范围是今天到未来 30 天,范围两端都允许;默认值是今天;用户选中后仍需点击现有的提交按钮才保存。使用DatePicker的selection绑定现有日期状态,并使用in:限制范围;这是日期字段时使用displayedComponents: .date,不要额外加入时间。保留现有提交、取消和错误提示逻辑。如果当前页面没有独立的暂存日期,请先说明取消操作会不会回写业务值,再给出最小改动方案。请先列出你改动前后的状态:未选择、已选择、提交中、提交失败、提交成功。最后给出 Xcode 验收步骤,覆盖范围边界、取消、错误恢复、大字号和 VoiceOver。
这条指令有意把
DatePicker 限定在一个字段。AI 如果顺手重写了整个表单,差异会变大,PM 反而很难判断它有没有改坏原来的提交逻辑。最小实现通常长这样,变量名和日期范围应由你的规则表决定:
@State private var selectedDate = Date()
private var allowedDates: ClosedRange<Date> {
let start = Calendar.current.startOfDay(for: Date())
let end = Calendar.current.date(byAdding: .day, value: 30, to: start)!
return start...end
}
DatePicker(
"预约日期",
selection: $selectedDate,
in: allowedDates,
displayedComponents: .date
)这里有三个验收重点:
selection 绑定的是哪一个状态,in: 的起止日期来自哪条业务规则,以及 displayedComponents 是否和字段含义一致。Apple 的 DatePickerComponents 文档提供了该参数的官方定义;不要把「日期」和「日期加时间」混成一个字段,再靠显示格式掩盖数据含义。4代码里的
! 只是为了突出结构,不应该成为你复制后的最终实现。让 AI 在正式代码中处理日期计算失败的情况,并检查它没有把某个固定日期偷偷写死。在 Xcode 里验收真正的边界
不要只看选择器能不能弹出来。用模拟器或真机逐项检查:
- 正常选择:选择范围中间的一天,页面上的日期文本、提交请求和成功结果都指向同一个值。
- 最小值和最大值:分别选择范围两端,确认两端是否符合规则;尝试范围外的日期,不能绕过界面直接提交成功。
- 旧值失效:先让页面带入一个合法日期,再把规则改成不包含它的范围。确认页面会清空、回退到合法值,或给出明确错误,不能继续显示一个看似有效的旧值。
- 取消与返回:在弹层里改日期后点取消或返回,检查业务值是否保持原样;如果产品要求立即生效,就把这个规则写进验收结果,不要让「取消」只是一个装饰按钮。
- 提交失败:模拟网络失败或服务端校验失败,检查日期仍保留,错误说明贴近字段,修正后可以再次提交。
- 地区与大字号:切换一个目标市场的地区格式并增大文字,确认日期顺序、月份名称、按钮和错误文案都能读完。不要把某一种模拟器显示样式当成所有用户都会看到的样子。
- VoiceOver:检查读屏时能听出字段名称、当前日期和可继续执行的动作;不能只依赖选中颜色判断当前值。
- 日期和时间边界:如果字段实际代表预约时刻,检查营业时间、门店所在地或时区规则是否也进入请求数据。仅仅把界面改成能选时间,不等于服务端知道这个时间属于哪里。
DatePicker 负责让用户选择日期,范围和保存时机仍然来自你的产品规则。尤其是「取消后是否保留」和「旧日期失效后怎么办」,组件不会替你做决定。PM 今天可以独立完成的清单
- 选一个仍靠手输日期或提交后才报错的页面。
- 写清日期含义、范围两端、默认值、空值和提交时机。
- 明确这是日期,还是带时区含义的具体时刻。
- 让 AI 只修改日期字段,先列状态再给最小差异。
- 检查
selection、in:和displayedComponents是否对应规则表。 - 在 Xcode 验收范围两端、旧值失效、取消、失败恢复和重复提交。
- 切换大字号、地区格式和 VoiceOver,再决定是否可以合并改动。
日期选择器的价值不在于把输入框换成一个系统控件,而在于把「什么日期才合法」提前变成用户能直接操作、PM 能直接验收的规则。先把范围和提交时机写下来,再让 AI 写代码,返工会少很多。
Related content
- Sign in to comment.
