SwiftUI加载和显示远程图片的AsyncImage
SwiftUI加载和显示远程图片的AsyncImage

SwiftUI加载和显示远程图片的AsyncImage

在 SwiftUI 中,AsyncImage 是一个用于加载和显示远程图片的视图组件,它从 iOS 15 开始支持。它会自动处理图片的下载、缓存以及错误处理,支持占位符视图显示。

基本用法

加载远程图片

AsyncImage(url: URL(string: "https://fangjunyu.com/wp-content/uploads/2024/03/egretBayLibrary.png"))

这是最简单的形式,加载图片时如果失败或图片正在加载,不会显示占位符或错误视图。

带占位符的用法

完整形式

AsyncImage(url: URL(string: "https://fangjunyu.com/wp-content/uploads/2024/03/jinan.png")) { image in
    image
        .resizable()
        .scaledToFit()
        .cornerRadius(10)
} placeholder: {
    ProgressView() // 显示加载占位符
}
.frame(width: 300, height: 300)

image 闭包:指定加载成功后图片的显示样式。

placeholder 闭包:指定图片加载时的占位符内容。

处理加载失败

可以通过 phase 来处理加载失败的情况:

AsyncImage(url: URL(string: "https://fangjunyu.com/wp-content/uploads/2024/03/1-150x150.png")) { phase in
    switch phase {
    case .empty:
        ProgressView() // 加载中
    case .success(let image):
        image
            .resizable()
            .scaledToFit()
            .cornerRadius(10)
    case .failure:
        Image(systemName: "xmark.circle") // 加载失败的占位图片
            .resizable()
            .scaledToFit()
            .foregroundColor(.red)
    @unknown default:
        EmptyView() // 未知情况
    }
}
.frame(width: 300, height: 300)

缓存控制

默认情况下,AsyncImage 使用系统级缓存来管理远程图片。如果需要更复杂的缓存控制,可以考虑第三方库,如 SDWebImageSwiftUI

异步任务加载图片

如果需要更复杂的逻辑,比如动态加载图片或手动处理错误,可以结合 async 和 await:

struct RemoteImageView: View {
    @State private var image: Image? = nil
    @State private var isLoading = false
    
    let url = "https://fangjunyu.com/wp-content/uploads/2024/03/icon.png"
    
    var body: some View {
        ZStack {
            if let image = image {
                image
                    .resizable()
                    .scaledToFit()
                    .frame(width: 300)
            } else if isLoading {
                ProgressView() // 加载中
            } else {
                Image(systemName: "photo")
                    .resizable()
                    .scaledToFit()
                    .foregroundColor(.gray)
            }
        }
        .onAppear {
            loadImage()
        }
    }
    
    private func loadImage() {
        guard let imageURL = URL(string: url) else { return }
        isLoading = true
        
        Task {
            do {
                let data = try await URLSession.shared.data(from: imageURL).0
                if let uiImage = UIImage(data: data) {
                    image = Image(uiImage: uiImage)
                }
            } catch {
                print("图片加载失败: \(error)")
            }
            isLoading = false
        }
    }
}

性能注意事项

如果图片资源较大,AsyncImage 会下载完整资源后渲染。对于高分辨率图片,可以考虑优化图片大小。

如果需要对本地图片资源优化加载,可以使用 UIImage 和 Image 自定义实现。

相关文章

SDWebImageSwiftUI:https://github.com/SDWebImage/SDWebImageSwiftUI

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开放者。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注