美文网首页
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