美文网首页
QuickLook框架详细解析(三) —— QuickLook

QuickLook框架详细解析(三) —— QuickLook

作者: 刀客传奇 | 来源:发表于2020-07-09 16:07 被阅读0次

版本记录

版本号 时间
V1.0 2020.07.09 星期四

前言

QuickLook框架提供了文档的预览功能。接下来几篇我们就一起看一下这个框架。感兴趣的可以看下面几篇。
1. QuickLook框架详细解析(一) —— 基本概览(一)
2. QuickLook框架详细解析(二) —— QuickLook 预览简单示例(一)

源码

1. Swift

首先看下工程组织结构

下面看一下sb中的内容

接着就是源码了

1. File.swift
import UIKit
import QuickLook

class File: NSObject {
  let url: URL

  init(url: URL) {
    self.url = url
  }

  var name: String {
    url.deletingPathExtension().lastPathComponent
  }
}

// MARK: - QLPreviewItem
extension File: QLPreviewItem {
  var previewItemURL: URL? {
    url
  }
}

// MARK: - QuickLookThumbnailing
extension File {
  func generateThumbnail(completion: @escaping (UIImage) -> Void) {
    // 1
    let size = CGSize(width: 128, height: 102)
    let scale = UIScreen.main.scale

    // 2
    let request = QLThumbnailGenerator.Request(
      fileAt: url,
      size: size,
      scale: scale,
      representationTypes: .all)

    // 3
    let generator = QLThumbnailGenerator.shared
    generator.generateRepresentations(for: request) { thumbnail, _, error in
      if let thumbnail = thumbnail {
        completion(thumbnail.uiImage)
      } else if let error = error {
        // Handle error
        print(error)
      }
    }
  }
}

// MARK: - Helper extension
extension File {
  static func loadFiles() -> [File] {
    let fileManager = FileManager.default
    guard let documentsURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first else { return [] }

    let urls: [URL]
    do {
      urls = try fileManager.contentsOfDirectory(at: documentsURL, includingPropertiesForKeys: nil)
    } catch {
      fatalError("Couldn't load files from documents directory")
    }

    return urls.map { File(url: $0) }
  }

  static func copyResourcesToDocumentsIfNeeded() {
    guard UserDefaults.standard.bool(forKey: "didCopyResources") else {
      let files = [
        Bundle.main.url(forResource: "Cover Charm", withExtension: "docx"),
        Bundle.main.url(forResource: "Light Charm", withExtension: "pdf"),
        Bundle.main.url(forResource: "Parapluie Spell", withExtension: "txt"),
        Bundle.main.url(forResource: "Water Spell", withExtension: "html"),
        Bundle.main.url(forResource: "Dark Magic", withExtension: "zip")
      ]
      files.forEach {
        guard let url = $0 else { return }
        do {
          let newURL = FileManager.default
            .urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent(url.lastPathComponent)
          try FileManager.default.copyItem(at: url, to: newURL)
        } catch {
          print(error.localizedDescription)
        }
      }

      UserDefaults.standard.set(true, forKey: "didCopyResources")
      return
    }
  }
}
2. FileCell.swift
import UIKit

class FileCell: UICollectionViewCell {
  static let reuseIdentifier = String(describing: FileCell.self)

  @IBOutlet weak var thumbnailImageView: UIImageView!
  @IBOutlet weak var nameLabel: UILabel!

  func update(with file: File) {
    nameLabel.text = file.name

    file.generateThumbnail { [weak self] image in
      DispatchQueue.main.async {
        self?.thumbnailImageView.image = image
      }
    }
  }
}
3. ViewController.swift
import UIKit
import QuickLook

class ViewController: UICollectionViewController {
  weak var tappedCell: FileCell?
  let files = File.loadFiles()

  override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    files.count
  }

  override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    guard let cell = collectionView.dequeueReusableCell(
      withReuseIdentifier: FileCell.reuseIdentifier,
      for: indexPath) as? FileCell
      else {
        return UICollectionViewCell()
    }
    cell.update(with: files[indexPath.row])
    return cell
  }

  override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    collectionView.deselectItem(at: indexPath, animated: true)
    let quickLookViewController = QLPreviewController()
    quickLookViewController.dataSource = self
    quickLookViewController.delegate = self
    tappedCell = collectionView.cellForItem(at: indexPath) as? FileCell
    quickLookViewController.currentPreviewItemIndex = indexPath.row
    present(quickLookViewController, animated: true)
  }
}

// MARK: - QLPreviewControllerDataSource
extension ViewController: QLPreviewControllerDataSource {
  func numberOfPreviewItems(in controller: QLPreviewController) -> Int {
    files.count
  }

  func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem {
    files[index]
  }
}

// MARK: - QLPreviewControllerDelegate
extension ViewController: QLPreviewControllerDelegate {
  func previewController(_ controller: QLPreviewController, transitionViewFor item: QLPreviewItem) -> UIView? {
    tappedCell?.thumbnailImageView
  }

  func previewController(_ controller: QLPreviewController, editingModeFor previewItem: QLPreviewItem) -> QLPreviewItemEditingMode {
    .updateContents
  }

  func previewController(_ controller: QLPreviewController, didUpdateContentsOf previewItem: QLPreviewItem) {
    guard let file = previewItem as? File else { return }
    DispatchQueue.main.async {
      self.tappedCell?.update(with: file)
    }
  }
}

后记

本篇主要讲述了QuickLook预览简单示例,感兴趣的给个赞或者关注~~~

相关文章

网友评论

      本文标题:QuickLook框架详细解析(三) —— QuickLook

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