SwiftUI 07-图像加载实战:为何我只用 `Image` 和 Kingfisher

图像是现代移动应用 UI 的核心组成部分。SwiftUI 为本地图像提供了简洁的 Image 视图,但在加载远程图片方面,虽然从 iOS 15 开始加入了 AsyncImage,但它实际使用场景非常有限,生产项目中我们通常会选择使用第三方库,如 KingfisherSDWebImageSwiftUI

一、使用 Image 展示本地图像

SwiftUI 的 Image 视图用于展示打包在项目中的资源图片,适用于 App 图标、界面装饰元素等。

Image("example")
    .resizable()
    .aspectRatio(contentMode: .fit)
    .frame(width: 200, height: 200)

使用建议

  • 图像需放入 Xcode 的 Asset Catalog;

  • 使用 .resizable() 让图片可缩放;

  • 配合 .aspectRatio.frame 控制布局。

二、异步加载远程图片:AsyncImage 是不是“鸡肋”?

从 iOS 15 开始,SwiftUI 引入了 AsyncImage 来加载远程图片:

AsyncImage(url: URL(string: "https://example.com/image.jpg"))

自定义加载过程

AsyncImage(url: URL(string: "https://example.com/image.jpg")) { phase in
    switch phase {
    case .empty:
        ProgressView() // 加载中
    case .success(let image):
        image.resizable().aspectRatio(contentMode: .fit)
    case .failure:
        Image(systemName: "photo") // 加载失败
    @unknown default:
        EmptyView()
    }
}

为什么我几乎不用 AsyncImage

问题点 描述
没有缓存 滚动时图片频繁加载,体验极差
无重试机制 网络抖动直接失败
无渐显动画 UI 不够丝滑
无缓存控制 无法指定缓存策略、超时等参数
缺乏扩展性 无法做图片处理(圆角、滤镜等)

因此:适合 demo / 教学,但不推荐用于真实项目。

三、推荐方案:使用 Kingfisher 加载网络图片

Kingfisher 是一个成熟的 Swift 图像加载库,拥有缓存、占位图、动画、图片处理等丰富功能。完美适配 SwiftUI。

示例:加载并缓存远程图片

import Kingfisher

KFImage(URL(string: "https://example.com/image.jpg"))
    .placeholder {
        ProgressView()
    }
    .resizable()
    .aspectRatio(contentMode: .fill)
    .clipShape(RoundedRectangle(cornerRadius: 10))

特点:

  • 自动缓存和复用图片资源;

  • 支持圆角、模糊、滤镜等;

  • 内建渐隐渐显、错误占位图、占位动画;

  • 支持 iOS、macOS、tvOS、watchOS;

四、封装一个通用头像组件(推荐)

封装后使用统一组件更好管理样式与逻辑:

import Kingfisher

struct AvatarView: View {
    let url: String
    var size: CGFloat = 64

    var body: some View {
        KFImage(URL(string: url))
            .placeholder {
                ProgressView()
            }
            .resizable()
            .cancelOnDisappear(true)
            .scaledToFill()
            .frame(width: size, height: size)
            .clipShape(Circle())
            .overlay(Circle().stroke(Color.gray.opacity(0.2), lineWidth: 1))
            .shadow(radius: 1)
    }
}

五、什么时候仍然可以用 AsyncImage

适合使用场景 示例
教程与学习 SwiftUI 基础课程、快速原型
简单工具 App 不关注流量、图片体验的内部项目
临时图片加载 生成 QRCode、加载本地服务器测试图等

如果你的图片只是短期、不可复用、无需缓存,那就用 AsyncImage 也无妨。

建议

想构建现代 SwiftUI App?图像加载的体验非常关键。不要怕引入三方库,Kingfisher 和 SDWebImage 都是成熟且稳定的解决方案,极大提升开发效率和用户体验。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • SwiftUI要求 iOS13.0+ 快捷键 control + option + 点击:出现属性编辑器 comm...
    余青松阅读 11,601评论 1 11
  • Text组件:用于显示文本内容 示例1:Text("Hello, World!"),显示"Hello, World...
    进击小岛阅读 9,928评论 0 3
  • 模板语法 文本 双大括号的文本插值 Message:{{msg}} v-once指令:一次性的指令,数据改变时,插...
    cq_春风呼呼的吹阅读 3,030评论 0 0
  • 在 SwiftUI 中,@State 和 @Binding 是用于管理视图状态的核心属性包装器,它们有不同的使用场...
    码农老张阅读 1,135评论 0 0
  • 7.1案例介绍 表单,在网页中的作用不可小视,主要负责数据采集的功能,比如你可以采集访问者的名字和e-mail地址...
    杰奎琳子阅读 3,126评论 0 2

友情链接更多精彩内容