首页 > 其他分享 >SwiftUI中AsyncImage的使用(一个高效的异步下载图片组件)

SwiftUI中AsyncImage的使用(一个高效的异步下载图片组件)

时间:2024-05-30 21:04:26浏览次数:24  
标签:200 异步 image 缺省 AsyncImage SwiftUI Image 加载

iOS开发者经常会遇到需要在应用中显示网络图像的场景,无论是获取和显示用户头像,展示产品图像,等等。在原来的UIKit中,如果我们要用系统的API还是稍微有点麻烦,很多开发的朋友都选择了第三方的框架去处理网络图片的请求缓存等等。

AsyncImageSwiftUI中一个强大的功能,它简化了在应用程序中异步加载和显示网络图像的过程。使用AsyncImage,可以无缝地处理图像加载,缺省视图,甚至错误处理,同时保持响应式用户界面。

不过这个组件需要iOS 15.0tvOS 15.0及以上的版本才能使用。

AsyncImage基本使用

AsyncImage使用共享的URLSession实例从指定的URL加载图像,然后显示它。例如:

在这里插入图片描述
AsyncImage最简单的使用方法就是只传入一个url,便会异步去加载这张图片,在图片加载出来之前,整个组件背景色为淡灰色,也可以认为缺省图就是一个淡灰色的背景。

我们也可以对AsyncImage添加很多的修饰符,比如backgroundcornerRadius等等,如果修改了background,那么在图片加载出来之前显示的就是这个设置的background
在这里插入图片描述

struct AsyncImageDemo: View {
  private let photoURL = URL(string: "https://picsum.photos/200")

  var body: some View {
    AsyncImage(url: photoURL)
      .frame(width: 200, height: 200)
      .background(Color.red)
      .cornerRadius(20)
      .shadow(color: .black.opacity(0.6) ,radius: 20, y: 10)
  }
}

placeholder

很多的时候我们都会设置图片在未加载完的显示内容,这不仅限于一个缺省的默认颜色,在加载图片时显示缺省视图可以显著增强用户体验。特别是在网络图像可能需要一些时间来获取的情况下。

通过下面的初始化方法,我们可以自定义缺省图。如果在加载时发生错误,将显示相同的缺省图。
在这里插入图片描述

struct AsyncImageDemo: View {
  private let photoURL = URL(string: "https://picsum.photos/200")

  var body: some View {
    AsyncImage(url: photoURL) { image in
      image
        .resizable()
        .background(Color.red)
        .cornerRadius(20)
        .shadow(color: .black.opacity(0.6) ,radius: 20, y: 10)
    } placeholder: {
      ProgressView()
        .progressViewStyle(.circular)
    }
    .frame(width: 200, height: 200)
  }
}

上面初始化方法里,第一个闭包返回了一个Image实例,我们可以对这个Image添加很多的修饰符。
第二个闭包里面就可以设置缺省图,这里显示了一个ProgressView组件,也可以设置为一个颜色组件,那就和基础用法里的一样了。
另外添加frame修饰符的时候,可以添加给Image,也可以添加给AsyncImage,区别就在于修饰的范围大小,添加给AsyncImage,那么ProgressView也是该尺寸。

处理请求error

如果想要获得对加载过程的更多控制,可以使用init(url:scale:transaction:content:)初始化方法,它接受一个内容闭包,该闭包返回一个AsyncImagePhase来指示加载操作的状态,返回一个适合当前阶段的视图:

AsyncImagePhase是一个枚举,它代表了图片加载的每个阶段:

@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
public enum AsyncImagePhase : Sendable {

    /// No image is loaded.
    case empty

    /// An image succesfully loaded.
    case success(Image)

    /// An image failed to load with an error.
    case failure(any Error)

    /// The loaded image, if any.
    ///
    /// If this value isn't `nil`, the image load operation has finished,
    /// and you can use the image to update the view. You can use the image
    /// directly, or you can modify it in some way. For example, you can add
    /// a ``Image/resizable(capInsets:resizingMode:)`` modifier to make the
    /// image resizable.
    public var image: Image? { get }

    /// The error that occurred when attempting to load an image, if any.
    public var error: (any Error)? { get }
}

在这里插入图片描述

AsyncImage(url: photoURL, transaction: Transaction(animation: .easeInOut)) { phase in
  switch phase {
    case .empty:
      ProgressView()
        .progressViewStyle(.circular)
    case .success(let image):
      image
        .resizable()
        .transition(.scale(scale: 0.1, anchor: .center))
    case .failure:
      Image(systemName: "questionmark.diamond")
        .imageScale(.large)
    @unknown default:
        EmptyView()
    }
}
.frame(width: 200, height: 200)

在闭包内,通过switch判断来决定每个阶段要显示的内容。

该初始化方法中还传入了transaction参数,它需要传入一个Transaction实例,用来决定AsyncImagePhase每个阶段的转场动画。

除了用switch判断每个阶段,也可以直接判断是否得到了图片或者error等,比如下面的代码:

struct AsyncImageDemo: View {
  private let photoURL = URL(string: "https://picsum.photos/200")

  var body: some View {
    AsyncImage(url: photoURL) { phase in
      if let image = phase.image {
        // Displays the loaded image.
        image
          .resizable()
          .cornerRadius(20)
          .shadow(color: .black.opacity(0.6) ,radius: 20, y: 10)
      } else if phase.error != nil {
        // Displays error view
        Image(systemName: "questionmark.diamond")
          .imageScale(.large)
      } else {
        // Displays loading view
        ProgressView()
          .progressViewStyle(.circular)
      }
    }
    .frame(width: 200, height: 200)
  }
}

写在最后

本篇文章主要介绍了如何使用AsyncImage视图下载和显示网络图像,这个组件大大的简化了我们加载网络图片的代码和相关的逻辑。

最后,希望能够帮助到有需要的朋友,如果您觉得有帮助,还望点个赞,添加个关注,笔者也会不断地努力,写出更多更好用的文章。

标签:200,异步,image,缺省,AsyncImage,SwiftUI,Image,加载
From: https://blog.csdn.net/guoyongming925/article/details/139313402

相关文章

  • 异步处理获取视频
    免费获取API地址的网站:https://api.apiopen.topasync和await的用法(asyncfunctionloadDate(){letresponse=awaitfetch("https://api.apiopen.top/api/getMiniVideo?page=0&size=20")letdata=awaitresponse.json()/......
  • C#管理异步线程
    管理异步线程usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Threading;usingSystem.Threading.Tasks;namespacePortClient{///<summary>///异步线程///*修改为枚举类型更合理///</summary>publicstati......
  • async/await处理异步操作
    在JavaScript中,async/await是用于处理异步操作的一种语法糖,它允许我们以同步的方式编写异步代码,从而使代码更加清晰和易于理解。当使用await关键字等待一个Promise对象时,有时候我们需要捕获可能出现的异常并进行处理。以下是关于await异常捕获的介绍:asyncfunctionfetchData()......
  • C# 异步高并发优化
    C#异步高并发优化在现代应用程序开发中,处理高并发请求是一个常见的需求。本文将介绍如何在C#中使用异步编程和并发控制技术,优化高并发场景下的应用性能。使用async和await进行异步编程C#中的async和await关键字简化了异步编程的实现,避免了阻塞线程,从而提高了应用的响应......
  • 同步、异步、阻塞、非阻塞、回调函数
    同步、异步、阻塞、非阻塞、回调函数一、同步、异步和回调函数1.概念程序在执行过程中会存在函数调用,区分同步和异步的关键点在于函数调用后主程序如何运行。同步:函数调用后,主程序等待着函数返回才会继续往下运行。异步:函数调用后,主程序不等待函数返回就继续往下运行。......
  • 异步数据加载与绑定设计: AsyncLoadHelper
    在现代应用程序开发中,异步数据加载和管理是一个普遍的需求。本文介绍了一个自定义的异步数据加载工具——AsyncLoadHelper。通过详细的设计和实现介绍,以及结合实际应用示例,展示了AsyncLoadHelper在简化异步操作、提高代码可读性和维护性方面的优势。在开发过程中,异步数据加载常常......
  • 第五章 并发基础中的Future异步回调模式
    案例:为了提升泡茶效率。下面分别是用阻塞模式和异步回调模式来实现其中的异步泡茶流程。为了异步执行整个泡茶流程,分别设计三条线程:主线程、清洗线程、烧水线程。(1)主线程(MainThread)的工作是:启动清洗线程、启动烧水线程,等清洗、烧水完成后,泡茶喝。(2)清洗线程(WashThread)的工作是:洗......
  • 【Python并发编程指南】多线程、多进程与异步编程比较与选择
    ......
  • C# 混淆加密大师1.1.0更新, 新增资源文件加密, 防虚拟机, 异步混淆等新功能
    C#混淆加密大师是一款强大的工具,专为保护C#开发的dll和exe文件而设计,适用于各种应用程序,包括Winform、WPF、Unity游戏以及控制台程序。它支持从.NetFramework2.0到.NetFramework4.x,以及.NETCore2.0直至最新的.NET8版本。C#混淆加密大师不仅提供代码加密混淆功能,还能对EXE文......
  • 同步通信与异步通信
    异步通信(AsynchronousCommunication)和同步通信(SynchronousCommunication)是计算机网络和计算机系统中两种不同的数据传输方式。它们的主要区别在于数据传输的控制方式和时间关系。同步通信(SynchronousCommunication)同步通信是指数据传输过程中,发送方和接收方的时钟是同步的,即......