SwiftUI AsyncImage

异步加载和显示图像的视图
iOS 15.0+iPadOS 15.0+macOS 12.0+Mac Catalyst 15.0+tvOS 15.0+watchOS 8.0+

此视图使用共享 URLSession 实例从指定的 URL 加载图像并显示。例如,您可以显示存储在服务器上的图标:

AsyncImage(url: URL(string: "https://cocoaz.com/icon.png"))
    .frame(width: 200, height: 200)

在图像加载之前,视图会显示一个填充可用空间的标准占位符。 加载成功完成后,视图会更新以显示图像。 在上面的示例中,图标比框架小,因此看起来比占位符小。

SwfitUI AsyncImage example

您可以使用 init(url:scale:content:placeholder:) 指定自定义占位符。 使用此初始化程序,您还可以使用 content 参数来操作加载的图像。 例如,您可以添加修饰符以使加载的图像可调整大小:

AsyncImage(url: URL(string: "https://cocoaz.com/icon.png")) { image in
    image.resizable()
} placeholder: {
    ProgressView()
}
.frame(width: 50, height: 50)

对于此示例,SwiftUI 首先显示一个 ProgressView,然后将图像缩放以适合指定的帧:

SwiftUI AsyncImage loading example

您不能将特定于图像的修饰符,例如 resizable(capInsets:resizingMode:) 直接应用于 AsyncImage。相反,将它们应用到您的内容闭包在定义视图外观时获得的 Image 实例。

要获得对加载过程的更多控制,请使用 init(url:scale:transaction:content:) 初始化程序,它采用接收 AsyncImagePhase 的内容闭包来指示加载操作的状态。 返回适合当前阶段的视图:

AsyncImage(url: URL(string: "https://cocoaz.com/icon.png")) { phase in
    if let image = phase.image {
        image // 显示加载的图像
    } else if phase.error != nil {
        Color.red // 表示错误 
    } else {
        Color.blue // 充当占位符
    }
}