如何从 QLThumbnailGenerator 正确返回图像?(斯威夫特用户界面)

Beg*_*ner 2 quicklook swiftui

我的问题 如何从 QLThumbnailGenerator.shared.generateRepresentations(for: ... ) 返回 cgImage?

我的挂断/尝试(下面的代码) 我的尝试有一个函数(第 13 行),它返回 ListView 条目的 CGImage(第 39 行)。我尝试使用空的 CGImage(第 18 行),但它的初始化参数令人困惑,并且对于简单的缩略图来说似乎过多。我可能会错误地处理这个问题。

注释 使用 CGImage,因此相同的代码可以同时适用于 iOS 和 MacOS Catalyst。(在 WWDC 2019 第 719 场会议中看到了这一点。)我尝试但未能从以下位置收集答案: - https://developer.apple.com/documentation/quicklookthumbnailing/creating_quick_look_thumbnails_to_preview_files_in_your_app - https://forums.developer.apple.com/message /375807

道歉/感谢 感谢您的耐心,因为答案可能很明显,而且我的词汇量可能不够。我愚蠢的大脑在没有一点实践经验的情况下就忽略了讲座,所以我从零编程知识开始了第一个应用程序作为隔离爱好。之后我会回到理论讲座。

结果视图.swift



import SwiftUI
import MobileCoreServices
import Combine
import QuickLookThumbnailing
import CoreImage
import UIKit

struct ResultsView: View {
    @EnvironmentObject var parsedScreeningData: ParsedScreeningData
    @EnvironmentObject var search: Search

    func generateThumbnail(ofThis: String) -> CGImage {
        let url = self.search.libraryFolder.appendingPathComponent(ofThis)
        let size: CGSize = CGSize(width: 68, height: 88)
        let request = QLThumbnailGenerator.Request(fileAt: url, size: size, scale: (UIScreen.main.scale), representationTypes: .all)
        let generator = QLThumbnailGenerator.shared

        var image = CGImage()

        generator.generateRepresentations(for: request) { (thumbnail, type, error) in
            DispatchQueue.main.async {
                if thumbnail == nil || error != nil {
                    assert(false, "Thumbnail failed to generate")
                } else {
                    image = thumbnail!.cgImage
                }
            }
        }
        return image
    }



var body: some View {
    VStack{

        List(search.searchResults) { datum in
            HStack {
                Image(self.generateThumbnail(ofThis: datum.PDFname), scale: (UIScreen.main.scale), label: Text("PDF"))
                Text("File: \(datum.PDFname)")
                Text("Cell line: \(self.parsedScreeningData.parsedScreeningData[datum.termFoundIndex].misidentifiedCellLine)")
                    .padding(.trailing, 10)
                    .padding(.leading, 10)
                Spacer()
                Image(systemName: "eyeglasses").foregroundColor(ColorManager.iconGreen)
                } // HStack
            } // List
        }// Vstack
        .colorMultiply(ColorManager.beigeMedium)
            .padding(.trailing, 0)
            .padding(.leading, 0)
            .listStyle(GroupedListStyle())

    } // body
} // ResultsView struct


struct ResultsView_Previews: PreviewProvider {
    static var previews: some View {
        ResultsView().environmentObject(ParsedScreeningData()).environmentObject(Search())
    }
}

Run Code Online (Sandbox Code Playgroud)

Asp*_*eri 5

缩略图生成是异步的,因此它需要一些包装视图,该视图等待生成的实用缩略图显示一些存根占位符,并在缩略图准备好时进行更新。

这是可能的解决方案

  1. 缩略图持有者视图的使用
List(search.searchResults) { datum in
    HStack {
        ThumbnailImageView(url: self.search.libraryFolder.appendingPathComponent(datum.PDFname))
        Text("File: \(datum.PDFname)")

        // ... other your code here
Run Code Online (Sandbox Code Playgroud)
  1. 缩略图本身
struct ThumbnailImageView: View {
    let url: URL

    @State private var thumbnail: CGImage? = nil

    var body: some View {
        Group {
            if thumbnail != nil {
                Image(self.thumbnail!, scale: (UIScreen.main.scale), label: Text("PDF"))
            } else {
                Image(systemName: "photo") // << any placeholder
                  .onAppear(perform: generateThumbnail) // << here !! 
            }
        }
    }

    func generateThumbnail() {
        let size: CGSize = CGSize(width: 68, height: 88)
        let request = QLThumbnailGenerator.Request(fileAt: url, size: size, scale: (UIScreen.main.scale), representationTypes: .all)
        let generator = QLThumbnailGenerator.shared

        generator.generateRepresentations(for: request) { (thumbnail, type, error) in
            DispatchQueue.main.async {
                if thumbnail == nil || error != nil {
                    assert(false, "Thumbnail failed to generate")
                } else {
                    DispatchQueue.main.async { // << required !!
                        self.thumbnail = thumbnail!.cgImage  // here !!
                    }
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)