You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SwiftUI中展示PDF、生成缩略图并实现保存、打印等操作

问题修复与实现方案

1. 修复PDFView布局异常问题

原有代码布局失效的核心原因是没有开启PDFView的自动缩放适配,且不需要手动传入size控制布局,SwiftUI的frame修饰符即可控制视图尺寸,修正后的封装代码如下:

import SwiftUI
import PDFKit

struct PDFKitRepresentedView: UIViewRepresentable {
    let data: Data
    // 可选配置:是否允许用户缩放、滚动
    let enableInteraction: Bool
    
    init(_ data: Data, enableInteraction: Bool = true) {
        self.data = data
        self.enableInteraction = enableInteraction
    }

    func makeUIView(context: Context) -> PDFView {
        let pdfView = PDFView()
        pdfView.document = PDFDocument(data: data)
        // 开启自动缩放适配视图尺寸
        pdfView.autoScales = true
        // 禁用/启用用户交互(缩略图场景可以禁用交互)
        pdfView.isUserInteractionEnabled = enableInteraction
        // 设置显示模式为单页连续滚动,可按需调整
        pdfView.displayMode = .singlePageContinuous
        return pdfView
    }

    func updateUIView(_ uiView: PDFView, context: Context) {
        uiView.document = PDFDocument(data: data)
    }
}

使用时直接通过frame控制尺寸即可:

// 缩略图场景
PDFKitRepresentedView(pdfData, enableInteraction: false)
    .frame(width: 100, height: 140)
    .cornerRadius(8)

// 完整查看页面
PDFKitRepresentedView(pdfData)
    .frame(maxWidth: .infinity, maxHeight: .infinity)

2. 更高性能的缩略图生成方案

不需要用PDFView渲染缩略图,直接用PDFKit自带的缩略图生成接口性能更好,代码示例:

func generatePDFThumbnail(data: Data, size: CGSize) -> UIImage? {
    guard let document = PDFDocument(data: data),
          let firstPage = document.page(at: 0) else { return nil }
    return firstPage.thumbnail(of: size, for: .mediaBox)
}

可以提前生成UIImage后用Image展示,点击后再跳转至完整PDF页面。

3. 保存、打印功能的标准实现

不需要完全自定义,系统提供了原生标准接口:

  • 保存、分享功能:封装UIActivityViewController为SwiftUI视图,调用后即可调出系统分享面板,支持保存到文件、分享到第三方App等系统自带能力
  • 打印功能:直接调用UIPrintInteractionController系统打印接口即可,支持所有系统标准打印配置

分享面板封装示例:

struct ShareSheet: UIViewControllerRepresentable {
    let items: [Any]
    
    func makeUIViewController(context: Context) -> UIActivityViewController {
        UIActivityViewController(activityItems: items, applicationActivities: nil)
    }
    
    func updateUIViewController(_ uiViewController: UIActivityViewController, context: Context) {}
}

使用时传入PDF数据即可:

.sheet(isPresented: $showShare) {
    ShareSheet(items: [pdfData])
}

打印功能调用示例:

func printPDF(data: Data) {
    guard UIPrintInteractionController.isPrintingAvailable else { return }
    let printController = UIPrintInteractionController.shared
    printController.printingItem = data
    printController.present(animated: true)
}

4. 浏览器打开PDF的方案对比

用SFSafariViewController打开PDF确实可以快速实现需求,Safari自带PDF预览、分享、打印、查找等功能,不需要自己封装上述能力,开发成本极低,但存在两个限制:

  • 自定义程度低,无法在PDF页面添加自定义业务控件
  • 交互逻辑完全遵循Safari的默认规则,无法自定义跳转、手势等操作
    如果你的需求没有特殊的自定义PDF交互要求,用Safari打开是性价比最高的方案。

内容的提问来源于stack exchange,提问作者alionthego

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 22:06:01