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

iOS 16下PDFView设置autoScales=true导致应用冻结问题求助

iOS 16下使用PDFView展示图片触发缩放断言错误导致应用冻结

问题描述

我在SwiftUI应用中用PDFView展示图片来实现捏合缩放功能,iOS 15上运行正常,但升级到iOS 16后,加载PhotoDetailView时应用直接冻结,模拟器和真机都出现这个问题。

代码示例

import SwiftUI
import PDFKit

struct PhotoDetailView: UIViewRepresentable {
    let image: UIImage

    func makeUIView(context: Context) -> PDFView {
        let view = PDFView()
        view.document = PDFDocument()
        guard let page = PDFPage(image: image) else { return view }
        view.document?.insert(page, at: 0)
        view.autoScales = true
        return view
    }

    func updateUIView(_ uiView: PDFView, context: Context) {
        // empty
    }
}

错误日志

在iOS 16.0模拟器运行时,控制台输出两个错误:

  • [Assert] -[UIScrollView _clampedZoomScale:allowRubberbanding:]: Must be called with non-zero scale
  • [Unknown process name] CGAffineTransformInvert: singular matrix.

已做排查

我定位到问题出在view.autoScales = true:设置该属性前view.scaleFactor为1.0,设置后直接变成0.0,这正是触发错误的原因。iOS 15模拟器也会输出这些错误,但图片仍能正常加载;注释掉view.autoScales = true后,图片可以加载,但尺寸远大于设备屏幕。

我想避免构建自定义图片查看器,只需要实现基础的捏合缩放功能,请问该如何解决?


解决方案

方案1:延迟设置autoScales属性

iOS 16中PDFView对autoScales的设置时机要求更严格,在视图未完成布局时直接设置会导致缩放比例计算异常。我们可以通过DispatchQueue.main.async延迟设置该属性,让视图先完成初始化布局:

func makeUIView(context: Context) -> PDFView {
    let view = PDFView()
    view.document = PDFDocument()
    guard let page = PDFPage(image: image) else { return view }
    view.document?.insert(page, at: 0)
    
    // 延迟到主队列下一轮循环设置autoScales,确保视图已完成布局
    DispatchQueue.main.async {
        view.autoScales = true
    }
    return view
}

方案2:手动计算初始缩放比例(更稳定)

如果延迟设置仍有问题,可以手动计算适配屏幕的初始缩放比例,同时配置缩放范围,替代autoScales的自动适配逻辑:

func makeUIView(context: Context) -> PDFView {
    let view = PDFView()
    view.document = PDFDocument()
    guard let page = PDFPage(image: image) else { return view }
    view.document?.insert(page, at: 0)
    
    // 设置缩放范围,满足捏合缩放需求
    view.minScaleFactor = 0.1
    view.maxScaleFactor = 5.0
    // 手动计算适配当前视图尺寸的缩放比例
    view.scaleFactor = view.scaleFactorForSizeToFit
    return view
}

问题原因

iOS 16对UIScrollView的缩放逻辑做了更严格的断言检查,当PDFView在未完成布局时设置autoScales = true,内部计算缩放比例时会出现零值,触发UIScrollView的断言错误,进而导致应用冻结。而iOS 15虽然会输出错误日志,但系统容错机制没有让应用崩溃或冻结。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 03:20:16