Edit PDFs, Images, and Videos Using Quick Look in iOS 13
The QuickLook framework introduced an editing mode

One of the lesser-known gems of iOS, the Quick Look Framework is useful for previewing documents in your application. During WWDC 2019, the framework got a nice upgrade with the introduction of editing mode.
QLPreviewController is the controller responsible for presenting contents of varying types in a view controller. Currently, it supports images, videos, PDFs, CSV, and iWork file types.
QLPreviewItemEditingMode is the new addition to the framework that allows us to annotate images and PDFs and trim or convert videos easily.
QLPreviewItemEditingMode embeds the PencilKit framework for editing images and PDFs.
Our Goal
- Exploring the new additions in the Quick Look framework
- Building an iOS Application that uses Quick Look for editing documents
- Saving the edited documents in the documents directory using the
FileManager
Final destination
By the end of this piece, we’ll be able to edit and save images, videos, and PDFs as shown below:

What’s New in iOS 13 QuickLook?
Besides the addition of QLPreviewItemEditingMode, the QLPreviewControllerDelegate protocol introduces three new optional delegate methods.
Handling editing mode capabilities
We can handle the editing mode by implementing the following method:
optional func previewController(_ controller: QLPreviewController, editingModeFor previewItem: QLPreviewItem) -> QLPreviewItemEditingModeIn the above method, we can set the return type as createCopy , default or updateContents to handle the editing results accordingly. updateContents overwrites the content of the QLPreviewItems in the FileManager. By default editing mode is off.
Saving the edited contents
Once the edit is done, we can save the modified contents using the below optional method:
func previewController(_ controller: QLPreviewController, didSaveEditedCopyOf previewItem: QLPreviewItem, at modifiedContentsURL: URL)The above method gets triggered when the EditingMode is createsCopy. It returns the URL of the modified content(the content resides in a temp location). We can then choose to handle the URL and save it in FileManager.
Notifying about edited contents
We can choose to update the user interface after being notified of the successful update of the QLPreviewItem. This gets triggered when the Editing Mode is updatesContent :
func previewController(_ controller: QLPreviewController, didUpdateContentsOf previewItem: QLPreviewItem)In the next section, we’ll be creating a simple iOS application that invokes the Quick Look preview with a sample image, video, and PDF that are available with the source code. Just import QuickLook in your ViewController to get started.
Setting Up QLPreviewController
The following code is used to present the Quick Look Preview controller in our application’s ViewController and enable the Editing Mode:
@objc func onButtonClick(sender: UIButton){
let previewController = QLPreviewController()
previewController.dataSource = self
previewController.delegate = self
previewController.setEditing(true, animated: true)
self.present(previewController, animated: true, completion: nil)
}Next, you need to conform to the QLPreviewControllerDelegate , QLPreviewControllerDataSource protocols and implement the delegate functions in your class.
Setting Up Our Data Source
For the data source, we’ve set up an array of file name literals that’ll be used to display the QLPreviewItems as shown below:
var items : [String] = ["sampleVideo.mp4", "samplePDF.pdf", "sampleImage.png"]Next, we need to implement the data source protocol methods in order to display the QLPreviewItems. The following code is responsible for displaying the data source files in QLPreviewItems :
extension ViewController: QLPreviewControllerDataSource {
func numberOfPreviewItems(in controller: QLPreviewController) -> Int {
return items.count
}
func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem {
print(controller.isEditing)
let name = self.items[index]
let file = name.components(separatedBy: ".")
let path = Bundle.main.path(forResource: file.first!, ofType: file.last!)
let url = NSURL(fileURLWithPath: path!)
return url as QLPreviewItem
}
}Saving Updated Contents
Finally, we’ll add the optional delegate functions in order to save the edited contents as a copy by using the FileManager :

