
别让图片加载只剩空白:用 AI + AsyncImage 补齐加载和失败状态
这一技教你让 AI 用 SwiftUI AsyncImage 把远程图片的加载中、成功和失败状态补完整,并用一张坏 URL 验收占位、失败文案和重试是否真的有效。
先把问题说清楚:图片失败不是空白
商品详情、头像、文章封面、用户上传的反馈图,都可能来自网络。最容易被忽略的情况是:图片还没到时页面先留一块空白,加载失败后仍是一块空白,用户分不清是内容还在加载、没有图片,还是 App 出了问题。
今天这一技是让 AI 用 SwiftUI
AsyncImage 接管一个已有的远程图片入口,并把加载中、加载成功、加载失败分别画出来。Apple 将 AsyncImage 定义为「异步加载并显示图片」的视图;它可以使用默认占位,也可以通过内容闭包自定义显示方式。1重点不是把图片换成某个 API,而是让用户在每个阶段都知道发生了什么:加载中可以等,成功后能看清,失败后知道图片没加载出来。
先做一张图片状态表
拿一个真实页面来做,不要先让 AI 全项目搜索替换。先在备忘录写下这 4 项:
| 状态 | PM 需要决定的内容 | 示例 |
|---|---|---|
| 加载中 | 占位区域多大,是否需要保留图片比例 | 商品图位置保留 4:3 高度,不让标题上下跳动 |
| 成功 | 图片如何裁切,是否需要圆角 | 商品主体完整可见,使用填充裁切 |
| 失败 | 用户看到什么,是否还有下一步 | 显示「图片加载失败」,保留一个可理解的重试入口 |
| 图片用途 | 给图片补什么可读名称 | 「蓝色帆布包正面」而不是「图片」 |
如果页面有头像、商品图和文章配图,分别写一行。它们的比例、裁切方式和失败后的行动通常不同。不要把一张通用的灰色方块套到所有图片上。
把这段话交给 AI
在 AI 编码工具里,选中当前负责显示远程图片的视图或文件,再发送下面的指令。把方括号里的内容换成你的实际页面信息:
请只修改 [页面/文件名] 中负责显示 [图片用途] 的远程图片入口,不要改动数据模型、上传流程、网络层和其他页面。
目标:用 SwiftUI AsyncImage 处理图片的加载中、成功、失败三个状态。
1. 先阅读现有图片 URL 的来源和视图尺寸,说明你找到的入口;不要凭空新建 URL。
2. 加载中显示与最终图片同尺寸的占位,避免图片到达后标题或按钮跳动。
3. 成功时保留当前的圆角、裁切和尺寸要求,并补上准确的 accessibility label。
4. 失败时显示用户能看懂的状态和图标;只有能真正再次触发加载的动作才叫「重试」,不要放一个没有效果的按钮。
5. 保持 iPhone 和 iPad 的现有布局,不引入新的第三方图片库。
6. 输出:改动文件、状态分支、需要我在 Xcode 或模拟器中执行的验收步骤,以及项目最低 iOS 版本是否满足该 API。Apple 的 WWDC21 示例说明,
AsyncImage 可以自动获取远程图片并提供默认占位,也可以自定义图片、占位内容、动画和错误处理;使用 phase 时,可以分别处理 .empty、.success 和 .failure。2这里有一个容易踩的产品坑:失败状态不等于已经有了重试能力。先要求 AI 说明它如何再次触发加载,再决定要不要保留「重试」按钮。若当前数据流没有可重复执行的加载动作,先显示明确失败状态,比摆一个点了没反应的按钮更诚实。
PM 看改动时只盯 5 个地方
- 状态是否完整。 代码里应能找到加载中、成功和失败三条路径;不要只看到一张图片外面包了一个转圈。
- 图片框是否稳定。 加载中和成功后的容器要有一致的尺寸或比例。列表滚动时,图片出现不能把文字、价格和按钮推来推去。
- 裁切是否服务于内容。 头像可以填充裁切,商品图可能需要完整显示。让 AI 解释它使用的裁切方式,并拿一张主体靠边的图片测试。
- 失败文案是否说人话。 不要把网络错误码直接展示给用户。文案至少要让人知道是图片没加载出来,而不是商品不存在。
- 重试是否真的重来。 点下重试后要能看到重新进入加载中,再出现成功或失败;如果只是改变了按钮样式,没有重新发起加载,就把它记成缺陷。
今天就做:用一张坏 URL 验收
不需要等后端配合,先在预览数据或测试入口里准备一张正常 URL 和一张确定不存在的图片 URL,然后按这个顺序走:
- 打开页面,确认图片到达前占位区域已经出现,标题和按钮位置不跳动。
- 换成正常图片,检查主体没有被关键裁切,圆角和容器尺寸与原设计一致。
- 换成不存在的 URL,确认页面不白屏,失败说明和图标仍在图片框内。
- 如果有重试,点一次,确认先出现加载中,再得到新结果;连续点击不会叠出多个按钮或重复跳转。
- 在列表里放入多张图片,向下滚动再返回,检查失败的一行不会把其他行的高度挤乱。
- 用 VoiceOver 读到图片时,确认它说的是内容名称;装饰性图片则不要制造多余朗读。
这套验收把「数据没有」和「图片没加载出来」分开了。对产品来说,前者需要空状态或补数据,后者需要网络、URL 或资源本身的处理,后续排查方向会完全不同。
这招的边界
AsyncImage 适合把一个已有远程图片入口的显示状态补完整。它不等于图片上传、复杂缓存策略、带鉴权请求或整套图片 CDN 方案。遇到这些需求时,让 AI 先列出当前项目的网络层和图片库,再决定是沿用现有能力,还是只把 AsyncImage 用在不需要额外请求配置的简单展示场景。今天的最小动作只有一个:找出页面里最容易出现空白的远程图片,写完状态表,交给 AI 只改这一处,然后用一张坏 URL 验证失败状态和重试是否诚实。
相似内容
- 登录后可发表评论。
More from this channel›
- 别让用户切回页面又重来:用 AI + @SceneStorage 保存 iOS 当前状态
- 别让按钮挤出屏幕:用 AI + ViewThatFits 给 iOS 布局准备兜底
- 别让弹层一上来盖满屏:用 AI + presentationDetents 让 iOS 操作按高度分层
- 别让慢请求覆盖新选择:用 AI + SwiftUI task(id:) 管住筛选结果
- 别让 iPad 版只是放大 iPhone:用 AI + NavigationSplitView 做双栏界面
- 别让页面跳转像迷宫:用 AI + NavigationStack 给 iOS 流程搭清楚路径
- 别让设置每次重置:用 AI + AppStorage 给 iOS 偏好做本地保存
- 别让头像上传卡在权限坑:用 AI + PhotosPicker 给 iOS 接上相册选择
