I'm working on an app that displays a PDF using PDFKit, and I need to be able to set the minimum zoom level - otherwise the user can just zoom out forever. I've tried to set minScaleFactor
and maxScaleFactor
, and because these turn off autoScales
, I need to set the scaleFactor
to pdfView.scaleFactorForSizeToFit
. However, this setting doesn't result in the same beginning zoom as autoScales
and despite changing the actual scaleFactor
number, the beginning zoom doesn't change. This photo is with autoScales
on:
[![image with autoscales on][1]][1]
and then what happens when I use the scaleFactorForSizeToFit
:
[![image with scaleFactorForSizeToFit][2]][2]
To quote the apple documentation for scaleFactorForSizeToFit
, this is the
"size to fit" scale factor that autoScales would use for scaling the current document and layout.
I've pasted my code below. Thank you for your help.
import PDFKit
import SwiftUI
import Combine
class DataLoader : ObservableObject {
@Published var data : Data?
var cancellable : AnyCancellable?
func loadUrl(url: URL) {
cancellable = URLSession.shared.dataTaskPublisher(for: url)
.map { $0.data }
.receive(on: RunLoop.main)
.sink(receiveCompletion: { (completion) in
switch completion {
case .failure(let failureType):
print(failureType)
//handle potential errors here
case .finished:
break
}
}, receiveValue: { (data) in
self.data = data
})
}
}
struct PDFSwiftUIView : View {
@StateObject private var dataLoader = DataLoader()
var StringToBeLoaded: String
var body: some View {
VStack {
if let data = dataLoader.data {
PDFRepresentedView(data: data)
.navigationBarHidden(false)
} else {
CustomProgressView()
//.navigationBarHidden(true)
}
}.onAppear {
dataLoader.loadUrl(url: URL(string: StringToBeLoaded)!)
}
}
}
struct PDFRepresentedView: UIViewRepresentable {
typealias UIViewType = PDFView
let data: Data
let singlePage: Bool = false
func makeUIView(context _: UIViewRepresentableContext<PDFRepresentedView>) -> UIViewType {
let pdfView = PDFView()
// pdfView.autoScales = true
// pdfView.maxScaleFactor = 0.1
pdfView.minScaleFactor = 1
pdfView.scaleFactor = pdfView.scaleFactorForSizeToFit
pdfView.maxScaleFactor = 10
if singlePage {
pdfView.displayMode = .singlePage
}
return pdfView
}
func updateUIView(_ pdfView: UIViewType, context: UIViewRepresentableContext<PDFRepresentedView>) {
pdfView.document = PDFDocument(data: data)
}
func canZoomIn() -> Bool {
return false
}
}
struct ContentV_Previews: PreviewProvider {
static var previews: some View {
PDFSwiftUIView(StringToBeLoaded: "EXAMPLE_STRING")
.previewInterfaceOrientation(.portrait)
}
}
I was eventually able to solve this. The following code is how I managed to solve it:
For some reason, the
pdfView.scaleFactorForSizeToFit
doesn't work - it always returns 0. This might be an iOS 15 issue - I noticed in another answer that someone else had the same issue. In the code above, what I did was I just scaled the PDF to fit the screen by screen height. This allowed me to more or less "autoscale" on my own. The code above autoscales the PDF correctly and prevents the user from zooming out too far.