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