djk3000 / ME

4 stars 2 forks source link

SwiftUI-PDF及缩略图应用 #101

Open djk3000 opened 1 year ago

djk3000 commented 1 year ago

PDFView使用方法

创建UIViewRepresentable,type为PDFView,然后传入pdf的地址(string -> url)传入就可以使用。

import PDFKit
import SwiftUI

struct PDFKitRepresentedView: UIViewRepresentable {
    typealias UIViewType = PDFView

    @Binding var url: URL?
    @Binding var pdfView: PDFView
    let singlePage: Bool

    func makeUIView(context _: UIViewRepresentableContext<PDFKitRepresentedView>) -> UIViewType {
        if let url = url {
            pdfView.document = PDFDocument(url: url)
        }
        pdfView.autoScales = true

        //默认模式(上下连贯的滑动模式)
        //单页模式(这是单页左右滑动的模式)        
        if singlePage {
            pdfView.displayMode = .singlePage
            pdfView.displayMode = .singlePage
            pdfView.displayDirection = .horizontal
            pdfView.usePageViewController(true)
        }
        return pdfView
    }

    func updateUIView(_ pdfView: UIViewType, context _: UIViewRepresentableContext<PDFKitRepresentedView>) {

    }
}

PDFThumbnail使用方法

和上面那个一样,这次的type使用PDFThumbnailView,可以和上面那个传入同一个pdf,把缩略图的指向同一个pdf,那两边就能联动了。

import PDFKit
import SwiftUI

struct PDFThumbnailRepresented : UIViewRepresentable {
    @Binding var url: URL?
    @Binding var pdfView: PDFView
    @Binding var pdfHeight: CGFloat

    typealias UIViewType = PDFThumbnailView

    func makeUIView(context: Context) -> PDFThumbnailView {
        if let url = url {
            pdfView.document = PDFDocument(url: url)
            //可以在外层套一个ScrollView,然后高度就是页数的高度
            DispatchQueue.main.async {
                self.pdfHeight = CGFloat(100 * (pdfView.document!.pageCount))
            }
        }

        let thumbnail = PDFThumbnailView()
        thumbnail.pdfView = pdfView
        thumbnail.thumbnailSize = CGSize(width: 100, height: 100)
        thumbnail.layoutMode = .vertical

        return thumbnail
    }    

    func updateUIView(_ uiView: PDFThumbnailView, context: Context) {

    }
}

PDF第一页作为封面

可以读取PDF的第一页作为缩略图的封面放在外面,将第一页转换为图片,然后可以外面设置图片的大小。

    func drawPDFfromURL(url: URL?) -> UIImage? {
        guard url != nil else { return UIImage(named: "") }
        guard let document = CGPDFDocument(url! as CFURL) else { return nil }
        guard let page = document.page(at: 1) else { return nil }

        let pageRect = page.getBoxRect(.cropBox)
        let renderer = UIGraphicsImageRenderer(size: pageRect.size)
        print("Page Width ------\(pageRect.size.width)")
        print("Page Height ------\(pageRect.size.height)")
        let img = renderer.image { ctx in
            UIColor.white.set()
            ctx.fill(pageRect)

            ctx.cgContext.translateBy(x: 0.0, y: pageRect.size.height)
            ctx.cgContext.scaleBy(x: 1.0, y: -1.0)

            ctx.cgContext.drawPDFPage(page)
        }

        return img
    }

参考资料