Making a zoomable Image, in SwiftUI
Welcome to this tutorial on creating a zoomable image in SwiftUI! If you've been struggling with various options for creating a zoomable image in SwiftUI, you're not alone.
While there are many solutions, some require tons of boilerplate, and others only work in UIKit. Some, finaly, simply work, until they don't run on UIKit. Others work, until they don't.
Having tried those, and looked into a few libraries (I especially liked this one, until I realized it would only stay zoomed in as long as you were actually pinching) , I can say JarWarren and Haolong were right. (Un)surprisingly, turning our image into a PDF document and displaying it using PDFKit
is the simplest way I've found so far to make a zoomable Image
you can pan around in SwiftUI (using UIViewRepresentable
).
For those of you struggling with it, here's my take on it (careful, it seems PDFKit has it's own weird quirks):
struct ZoomableImage: UIViewRepresentable {
// used to set the image that will be displayed in the PDFView
private(set) var image: UIImage
// sets the background color of the PDFView
private(set) var backgroundColor: Color
// sets the minimum scale factor for zooming out of the image
private(set) var minScaleFactor: CGFloat
// sets the ideal scale factor for the image when it is first displayed in the PDFView
// the initial zoom level of the image when it is first displayed
private(set) var idealScaleFactor: CGFloat
// sets the maximum scale factor for zooming in on the image
private(set) var maxScaleFactor: CGFloat
public init(
image: UIImage,
backgroundColor: Color,
minScaleFactor: CGFloat,
idealScaleFactor: CGFloat,
maxScaleFactor: CGFloat
) {
self.image = image
self.backgroundColor = backgroundColor
self.minScaleFactor = minScaleFactor
self.idealScaleFactor = idealScaleFactor
self.maxScaleFactor = maxScaleFactor
}
public func makeUIView(context: Context) -> PDFView {
let view = PDFView()
guard let page = PDFPage(image: image) else { return view }
let document = PDFDocument()
document.insert(page, at: 0)
view.backgroundColor = UIColor(cgColor: backgroundColor.cgColor!)
view.autoScales = true
view.document = document
view.maxScaleFactor = maxScaleFactor
view.minScaleFactor = minScaleFactor
view.scaleFactor = idealScaleFactor
return view
}
public func updateUIView(_ uiView: PDFView, context: Context) {
// empty
}
}
It is important to note that the idealScaleFactor
should be between the minScaleFactor
and maxScaleFactor
. If not, the idealScaleFactor
will be set to the closest of minScaleFactor
or maxScaleFactor
.
Conclusion
In conclusion, creating a zoomable image in SwiftUI can be a bit tricky, but using PDFKit
to turn the image into a PDF document and display it using a PDFView
is a ridiculous yet simple and effective solution.Thanks for reading, and have a great day!