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

在draw(_:)方法中将PDFPage绘制到UIView子类,缩放适配矩形异常

解决PDFPage绘制到UIView时的缩放/适配问题

我来帮你搞定这个PDF页面适配的问题!你遇到的缩放/变换失效,大概率是没处理好UIKit和PDF坐标系的差异,加上之前的缩放逻辑没补全。咱们一步步来修复:

问题根源

UIKit的坐标系原点在左上角,但PDF的坐标系原点在左下角,直接缩放会导致页面显示颠倒或者位置偏移;另外你之前的代码里scaleBy的比例值没计算完整,这也是适配失效的核心原因。

完整修复后的代码

class PDFPageView: UIView {
    private let page: PDFPage
    
    init(frame: CGRect, page: PDFPage) {
        self.page = page
        super.init(frame: frame)
        // 给view设置白色背景,避免PDF透明区域显示底层内容
        backgroundColor = .white
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func draw(_ rect: CGRect) {
        guard let context = UIGraphicsGetCurrentContext() else { return }
        
        // 获取PDF页面的实际内容边界(媒体框)
        let pageBounds = page.bounds(for: .mediaBox)
        
        // 第一步:修正坐标系差异
        // 先把上下文平移到view底部,再翻转Y轴,对齐PDF的坐标系
        context.translateBy(x: 0, y: bounds.height)
        context.scaleBy(x: 1.0, y: -1.0)
        
        // 第二步:计算适配缩放比例(按你的需求暂不考虑宽高比)
        let scaleX = bounds.width / pageBounds.width
        let scaleY = bounds.height / pageBounds.height
        context.scaleBy(x: scaleX, y: scaleY)
        
        // 第三步:绘制PDF页面到当前上下文
        page.draw(with: .mediaBox, to: context)
    }
}

额外优化:如果之后需要等比例适配

要是你之后想保持PDF页面的宽高比,只需要调整缩放比例的计算逻辑,再加上居中平移即可:

// 替换原有的缩放比例计算部分
let scale = min(bounds.width / pageBounds.width, bounds.height / pageBounds.height)
context.scaleBy(x: scale, y: scale)

// 计算居中偏移量,让PDF页面在view中居中显示
let translateX = (bounds.width - pageBounds.width * scale) / 2
let translateY = (bounds.height - pageBounds.height * scale) / 2
context.translateBy(x: translateX, y: translateY)

这样修改后,PDF页面就能正确适配你的UIView了~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:20:02