实现显示网络图片功能

773 阅读1分钟

AsyncImage

AsyncImage 是 iOS 15 之后 SwiftUI 提供的用于加载网络图片的异步加载组件,适用于简单的网络图片加载需求。

示例代码:

AsyncImage(url: URL(string: data.icon ?? "")) { image in
    image
        .resizable()
        .scaledToFill()
        .frame(width: 64, height: 64)
        .clipShape(RoundedRectangle(cornerRadius: 10))
} placeholder: {
    Color.gray
        .frame(width: 64, height: 64)
        .clipShape(RoundedRectangle(cornerRadius: 10))
}

详细状态

AsyncImage(url: icon) { phase in
    switch phase {
    case .success(let image):
        image
            .resizable()
            .aspectRatio(contentMode: .fill)
    case .failure:
        Image(systemName: "xmark.circle")
            .resizable()
            .scaledToFit()
    case .empty:
        EmptyView()
    default:
        EmptyView()
    }
}

优点:

  • 原生支持,无需引入第三方库。
  • 简单适用,但不支持缓存和高级的图片处理功能。

缺点:

  • 无法处理图片缓存,且占位图设置不够灵活。
  • 仅适用于 iOS 15 及以上版本

Kingfisher

Kingfisher 是一个强大的第三方库,支持图片缓存、图片下载、以及处理占位图、图片解码等高级功能。

安装 Kingfisher:

可以使用 Swift Package Manager 或 CocoaPods 安装 Kingfisher。

使用 Swift Package Manager:

  1. 打开 Xcode 项目。
  2. 选择菜单栏的File > Add Packages...
  3. 在搜索栏中输入https://github.com/onevcat/Kingfisher,选择最新版本并添加到项目中。
if let icon = data.icon?.url {
    KFImage.url(icon)
        .onProgress { receivedSize, totalSize in  }
        .onSuccess { result in  }
        .onFailure { error in}
        .resizable()
        .aspectRatio(contentMode: .fill)
        .frame(width: 120, height: 120)
        .background(.divider) // LocalDividerColor equivalent
        .clipShape(extraSmallShape)
} else {
    Image("placeholder")
        .resizable()
        .aspectRatio(contentMode: .fill)
        .frame(width: 120, height: 120)
        .background(.outline)
        .clipShape(extraSmallShape)
}

优点:

  • 支持图片缓存,提升加载速度。
  • 提供丰富的图片处理和显示功能,如滤镜、占位符、解码等。
  • 支持更广泛的 iOS 版本(iOS 11+)。

缺点:

  • 需要引入第三方库,增加了项目的依赖。

总结

  • AsyncImage 适用于简单的网络图片加载需求,特别是在不需要缓存的场景下。
  • Kingfisher 更加灵活,适合需要缓存、多功能图片处理的场景。