美文网首页
Nuke框架详细解析(三) —— 简单使用示例(二)

Nuke框架详细解析(三) —— 简单使用示例(二)

作者: 刀客传奇 | 来源:发表于2020-10-10 12:58 被阅读0次

    版本记录

    版本号 时间
    V1.0 2020.10.10 星期六

    前言

    在我们开发中总有从远程下载图片,OC中有个很成熟的三方框架,大家都知道的SDWebImage,同样Swift中也有类似的三方框架Nuke,接下来几篇我们就一起看一下这个框架。
    1. Nuke框架详细解析(一) —— 基本概览(一)
    2. Nuke框架详细解析(二) —— 简单使用示例(一)

    源码

    1. Swift

    首先看下工程组织结构

    接着看下sb中的内容

    下面就是代码了

    1. PhotoCell.swift
    
    import UIKit
    import Nuke
    
    class PhotoCell: UICollectionViewCell {
      @IBOutlet weak var imageView: UIImageView!
    }
    
    2. PhotoGalleryViewController.swift
    
    import UIKit
    import Nuke
    import ImagePublisher
    
    class PhotoGalleryViewController: UICollectionViewController {
      var photoURLs: [URL] = []
    
      let cellSpacing: CGFloat = 1
      let columns: CGFloat = 3
      var cellSize: CGFloat = 0
    
      var pixelSize: CGFloat {
        return cellSize * UIScreen.main.scale
      }
    
      var resizedImageProcessors: [ImageProcessing] {
        let imageSize = CGSize(width: pixelSize, height: pixelSize)
        return [ImageProcessors.Resize(size: imageSize, contentMode: .aspectFill)]
      }
    
      override func viewDidLoad() {
        super.viewDidLoad()
    
        title = "NASA Photos"
    
        guard
          let plist = Bundle.main.url(forResource: "NASAPhotos", withExtension: "plist"),
          let contents = try? Data(contentsOf: plist),
          let plistSerialized = try? PropertyListSerialization.propertyList(from: contents, options: [], format: nil),
          let urlPaths = plistSerialized as? [String]
          else {
            return
        }
    
        photoURLs = urlPaths.compactMap { URL(string: $0) }
    
        let contentModes = ImageLoadingOptions.ContentModes(
          success: .scaleAspectFill,
          failure: .scaleAspectFit,
          placeholder: .scaleAspectFit)
    
        ImageLoadingOptions.shared.placeholder = UIImage(named: "dark-moon")
        ImageLoadingOptions.shared.failureImage = UIImage(named: "annoyed")
        ImageLoadingOptions.shared.transition = .fadeIn(duration: 0.5)
        ImageLoadingOptions.shared.contentModes = contentModes
    
        DataLoader.sharedUrlCache.diskCapacity = 0
    
        let pipeline = ImagePipeline {
          let dataCache = try? DataCache(name: "com.raywenderlich.Far-Out-Photos.datacache")
          dataCache?.sizeLimit = 200 * 1024 * 1024
          $0.dataCache = dataCache
        }
        ImagePipeline.shared = pipeline
      }
    }
    
    // MARK: Collection View Data Source Methods
    extension PhotoGalleryViewController {
      override func collectionView(
        _ collectionView: UICollectionView,
        numberOfItemsInSection section: Int
      ) -> Int {
        return photoURLs.count
      }
    
      override func collectionView(
        _ collectionView: UICollectionView,
        cellForItemAt indexPath: IndexPath
      ) -> UICollectionViewCell {
        guard let cell = collectionView.dequeueReusableCell(
          withReuseIdentifier: "PhotoCell",
          for: indexPath) as? PhotoCell else {
            return UICollectionViewCell()
        }
    
        let request = ImageRequest(
          url: photoURLs[indexPath.row],
          processors: resizedImageProcessors)
    
        Nuke.loadImage(with: request, into: cell.imageView)
    
        return cell
      }
    }
    
    // MARK: Collection View Delegate Flow Layout Methods
    extension PhotoGalleryViewController: UICollectionViewDelegateFlowLayout {
      func collectionView(
        _ collectionView: UICollectionView,
        layout collectionViewLayout: UICollectionViewLayout,
        sizeForItemAt indexPath: IndexPath
      ) -> CGSize {
        if let layout = collectionViewLayout as? UICollectionViewFlowLayout {
          let emptySpace = layout.sectionInset.left + layout.sectionInset.right + (columns * cellSpacing - 1)
          cellSize = (view.frame.size.width - emptySpace) / columns
          return CGSize(width: cellSize, height: cellSize)
        }
    
        return CGSize()
      }
    
      func collectionView(
        _ collectionView: UICollectionView,
        layout collectionViewLayout: UICollectionViewLayout,
        minimumLineSpacingForSectionAt section: Int
      ) -> CGFloat {
        return cellSpacing
      }
    
      func collectionView(
        _ collectionView: UICollectionView,
        layout collectionViewLayout: UICollectionViewLayout,
        minimumInteritemSpacingForSectionAt section: Int
      ) -> CGFloat {
        return cellSpacing
      }
    }
    
    // MARK: Collection View Delegate Methods
    extension PhotoGalleryViewController {
      override func collectionView(
        _ collectionView: UICollectionView,
        didSelectItemAt indexPath: IndexPath
      ) {
        guard let photoViewController = PhotoViewController.instantiate() else {
          return
        }
    
        photoViewController.imageURL = photoURLs[indexPath.row]
        photoViewController.resizedImageProcessors = resizedImageProcessors
    
        navigationController?.pushViewController(photoViewController, animated: true)
      }
    }
    
    3. PhotoViewController.swift
    
    import UIKit
    import Nuke
    import Combine
    import ImagePublisher
    
    class PhotoViewController: UIViewController {
      var imageURL: URL?
      var cancellable: AnyCancellable?
      var resizedImageProcessors: [ImageProcessing] = []
    
      @IBOutlet weak var imageView: UIImageView!
    
      override func viewDidLoad() {
        super.viewDidLoad()
    
        imageView.image = ImageLoadingOptions.shared.placeholder
        imageView.contentMode = .scaleAspectFit
    
        guard let imageURL = imageURL else { return }
    
        loadImage(url: imageURL)
      }
    
      func loadImage(url: URL) {
        let resizedImageRequest = ImageRequest(
          url: url,
          processors: resizedImageProcessors)
        let resizedImagePublisher = ImagePipeline.shared.imagePublisher(with: resizedImageRequest)
        let originalImagePublisher = ImagePipeline.shared.imagePublisher(with: url)
    
        guard let failedImage = ImageLoadingOptions.shared.failureImage else {
          return
        }
    
        cancellable = resizedImagePublisher.append(
          originalImagePublisher)
          .map {
            ($0.image, UIView.ContentMode.scaleAspectFill )
          }
          .catch { _ in
            Just((failedImage, .scaleAspectFit))
          }
          .sink {
            self.imageView.image = $0
            self.imageView.contentMode = $1
          }
      }
    
      static func instantiate() -> PhotoViewController? {
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        return storyboard.instantiateViewController(
          withIdentifier: "PhotoViewController") as? PhotoViewController
      }
    }
    

    后记

    本篇主要讲述了Swift中的三方框架Nuke的简单使用示例,感兴趣的给个赞或者关注~~~

    相关文章

      网友评论

          本文标题:Nuke框架详细解析(三) —— 简单使用示例(二)

          本文链接:https://www.haomeiwen.com/subject/ajglpktx.html