[英]iOS PDFKit adjust pdf frame in PDFView
我有一个 PDF 具有不同高度的页面,我想以水平分页的方式显示,一次一页,页面之间没有间隙,并且每个页面的顶部与视图的顶部对齐。 例如:
我想使用PDFKit
的PDFView
,特别是因为这些设置可以通过以下方式实现:
let pdfView = PDFView()
pdfView.displayDirection = .horizontal
pdfView.displaysPageBreaks = false
pdfView.usePageViewController(true, withViewOptions: nil)
但是,这会产生以下结果:
这是由于页面的高度不同。 每个页面在PDFView
中垂直居中,如果页面的高度大于视图的高度(例如第 2 页),则按纵横比缩放以适应。
为了尝试解决第一个问题,垂直偏移,我尝试了几件事。 首先,这很严重,我知道这是错误的,在检查视图层次结构并找到页面呈现的私有视图(名为PDFTextInputView
的 class 的视图)我尝试将其框架的origin.y
调整为0
时最外层的滚动视图(另一个私有视图)滚动。 这是因为每当下一页或上一页滚动到视图中时,页面都会呈现在视图的顶部。 但是,一旦用户在该页面上进行捏合缩放,它的框架就会自动跳回居中。 除了依赖私有视图层次结构之外,这种方法是行不通的。
为了尝试解决“高页面问题”(第 2 页),我尝试在出现新页面时调整 PDFView 的比例因子。 可悲的是, .PDFViewPageChanged
通知仅在滚动视图结束减速后触发,因此页面在滚动时被缩小,然后当我调整比例因子时它会跳转以适应屏幕的宽度。 然后我转向.PDFViewVisiblePagesChanged
,它会在下一个/上一个页面进入视图时触发(以及更多次,这很好),这与.PDFViewPageChanged
有相同的问题。
我尝试过的其他事情:
transform
pdfView.usePageViewController
)有人对我如何实现我所追求的有任何想法吗?
所以事实证明,在挖掘了一些更多的私有 API(是的,这个解决方案仍然很恶心)之后,我在PDFScrollView
(一个私有的内部视图)上完全忽略了这个神奇的属性,称为......
forcesTopAlignment
要启用此功能,请在您的PDFView
PDFScrollView
:
pdfScrollView.setValue(true, forKey: "forcesTopAlignment")
这样就行了!
经过几天的努力,我终于找到了一种让PDFView
表现出我想要的方式的方法。
披露:该解决方案使用方法混合并依赖于私有视图层次结构,并且可能随时中断。 也就是说,它现在有效,我对解决方案感到满意。
此要点中提供了完整的解决方案。 (肉在overrideCenterAlign
。)
有一个名为_centerAlign
的私有方法,当 pdf 页面出现在屏幕上并使用捏合手势进行缩放时,它会垂直居中并缩放它们。 Swizzling 该方法允许我注入我自己的逻辑并将我自己的转换应用到 position pdf 查看我想要的方式(页面顶部与视图顶部对齐。)
有两种情况需要考虑。 “短页”案例(示例中的第 1、3、4 页)和“高页”案例(示例中的第 2 页)。在这两种情况下,我首先调用_centerAlign
的原始实现,以便它可以应用它的转换和管理更新内部滚动视图。
综上所述,我对不依赖私有方法和视图层次结构的更清洁的解决方案持开放态度。 如果您知道实现此目的的更好方法,请发布答案!
只需将 forceTopAlignment 设置为 true
例子:
lazy var pdfView: PDFView = {
let pdf = PDFView()
pdf.displayMode = .singlePageContinuous
pdf.autoScales = true
pdf.translatesAutoresizingMaskIntoConstraints = false
pdf.setValue(true, forKey: "forcesTopAlignment")
return pdf
}()
我的答案与接受的答案有何不同?
pdfView 上没有可用的滚动视图属性。 因此,您只需将值直接设置为 pdfView。
我认为问题在于将 PDFView 添加到有约束的视图中。 当我只使用 addSubview() 和用户正确的框架添加时,它不需要调用 setValue。
让 pdfView = PDFKit.PDFView(frame: self.view.bounds) pdfView.document = PDFKit.PDFDocument(url: url) pdfView.autoresizingMask = [.flexibleHeight, .flexibleWidth] view.addSubview(pdfView)
注意:此答案旨在帮助其他到达这里尝试解决类似问题的人。
自从苹果在 iOS13 中引入“拖动隐藏”(Apple “https://developer.apple.com/design/human-interface-guidelines/ios/app-architecture/modality/”)以来,我在 iOS12 中发现了一个令人讨厌的错误。
如果目标是 iOS13 或更高版本,一切正常。
在 iOS12 中,可能是由于计算大小不同,(我猜..) pdf 呈现错误:某些内容 go 向右并被剪掉。
一个肮脏的修复包括不打电话
self?.pdfView.autoScales = true
在 viewDidLoad 中,
但是在加载每个 PDF 后等待一些毫秒并设置它:
if #available(iOS 13.0, *) {
// NADA.. go on..
}else{
self.pdfView.autoScales = false // disable it.
self?.pdfView.alpha = 1
}
let pdf = load .......
self.pdfView.document = pdf
if #available(iOS 13.0, *) {
//nada..
} else {
// hack for ios 12
let when = DispatchTime.now() + 0.25
DispatchQueue.main.asyncAfter(deadline: when, execute: { [weak self] in
self?.pdfView.autoScales = true // hack for ios 12
self?.pdfView.alpha = 1
})
}
使用 alpha 防止查看 pdf 尚未采用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.