previewController previewItemAt not being called. iOS 10, swift 3, simulator - ios

I created a new view controller in storyboard. Connected it to the ListViewController. The ListViewController fills in the correct data to aboutDict[String:Any]. The fileURLs[] is built and func numberOfPreviewItems(in: QLPreviewController) -> Int is called - the debugger shows the fileURLs[] is as expected:
Printing description of self.fileURLs: ▿ 1 element
- 0 : file:///Users/kent/Library/Developer/CoreSimulator/Devices/5E23825C-DF99-455A-BEB1-F73398E7759F/data/Containers/Bundle/Application/307ED7DF-C07C-4C0A-BA78-938BABE7C22C/WINSystemInfo.app/ID-51A_E_PLUS2.pdf`
But func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem and func previewController(_ controller: QLPreviewController, shouldOpen url: URL, for item: QLPreviewItem) -> Bool are not called.
I get a nice ViewController that was pushed into the navigation stack with the correct name for the back button, and a gray page with centered text "No file to preview".
On pressing 'back' button, func previewControllerWillDismiss(_ controller: QLPreviewController) is called. So some of the delegate and datasource functions are being called.
I must be missing something simple...
I attached my class FileViewController.swift below:
class FileViewController: QLPreviewController, QLPreviewControllerDelegate, QLPreviewControllerDataSource {
var aboutDict = [String: Any]()
// QuickLook data
var fileURLs = [QLPreviewItem]()
// MARK: - Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
let filename = aboutDict["filename"] as! String?
let filetype = aboutDict["filetype"] as! String?
title = aboutDict["title"] as! String?
dataSource = self
delegate = self
if let fileUrl = Bundle.main.url(forResource: filename, withExtension: filetype, subdirectory: nil, localization: nil)
{
let filePreview = fileUrl as QLPreviewItem
fileURLs.append(filePreview)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Preview controller datasource functions
func numberOfPreviewItems(in: QLPreviewController) -> Int {
return fileURLs.count
}
func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem {
return fileURLs[index]
}
// MARK: - Preview controller delegate functions
func previewControllerWillDismiss(_ controller: QLPreviewController) {
debug("previewControllerWillDismiss")
}
func previewController(_ controller: QLPreviewController, shouldOpen url: URL, for item: QLPreviewItem) -> Bool {
return true
}
}
What am I missing?
Thank you.

I just had this problem and it was simply because I had forgotten to set my datasource on the QLPreviewController...

Related

QuickLook/QLPreviewController PDF Text Annotation background becomes black and font becomes small

I am Using QLPreviewController for editing the PDF. Everything is working properly but
if I add text annotation from the QLPreviewController and click on the done button it is working as expected I am getting the URL with edited PDF and if I do other changes for example add image annotation from outside of QLPreviewController and save that pdf using the code
self.pdfDocument.write(to: self.pdfUrl)
and if I open that pdf in the QLPReviewController and tap on the previously added text then the text annotation background becomes Black and the font becomes small.
I have attached the video please check.
**Video Link : ** https://www.dropbox.com/s/m0ql1csr8pars3t/Issue_video.mov?dl=0
I have used the below code for pdf mark up
func openPreview(_ url : URL){
let previewController = QLPreviewController()
previewController.isEditing = true
previewController.delegate = self
self.pdfUrl = url
previewController.dataSource = self
previewController.modalPresentationStyle = .overFullScreen
self.present(previewController, animated: true, completion: nil)
}
extension ViewController : QLPreviewControllerDataSource,QLPreviewControllerDelegate{
func numberOfPreviewItems(in controller: QLPreviewController) -> Int {
return 1
}
func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem {
return self.pdfUrl as QLPreviewItem
}
func previewController(_ controller: QLPreviewController, editingModeFor previewItem: QLPreviewItem) -> QLPreviewItemEditingMode {
return .updateContents
}
func previewControllerWillDismiss(_ controller: QLPreviewController) {
}
func previewController(_ controller: QLPreviewController, didUpdateContentsOf previewItem: QLPreviewItem) {
DispatchQueue.main.async {
self.pdfUrl = previewItem.previewItemURL
self.setPDFFile()
self.pdfDocument.write(to: self.pdfUrl)
}
}
}
func setPDFFile(){
if let doc = PDFDocument(url: self.pdfUrl){
self.pdfDocument = doc
self.pdfView.document = doc
}
}

Can we add text, shape and signature in Photo Markup with Pencil Kit?

I am not getting any option to add text, shape and signature while markup a photo with PencelKit in my app. This option is available in Apple's Photos App. I have tried to access this with various properties of CanvasView and PKToolPicker, but with no success.
self.canvasView?.drawing = PKDrawing()
self.canvasView.allowsFingerDrawing = true
if let window = self.view.window, let toolPicker = PKToolPicker.shared(for: window) {
toolPicker.setVisible(true, forFirstResponder: self.canvasView)
toolPicker.addObserver(self.canvasView)
self.canvasView.becomeFirstResponder()
}
I figured it out, finally! It's the QLPreviewController!
Editing with shapes, arrows and signature is only available for iOS13+.
First of all we need to read the file from an url, so set it up with init. I go with something like this as base and append the filename, also with file extension, e.g. .pdf:
FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last!
You can't save it in the tempDirectory, because the QLPreviewViewController needs access. No permission could result in an error like this:
AX Lookup problem - errorCode:1100 error:Permission denied portName:
Your customVC should look like this:
import UIKit
import QuickLook
class CustomVC: UIViewController {
var url: URL
init(url: URL) {
self.url = url
}
....func viewDidLoad() and stuff ......
func editFile() {
let editor = QLPreviewController()
editor.dataSource = self
editor.delegate = self
editor.setEditing(true, animated: true)
present(editor, animated: true, completion: nil)
}
}
// Load the file in the QLPreviewController with DataSource
extension CustomVC: QLPreviewControllerDataSource {
func numberOfPreviewItems(in controller: QLPreviewController) -> Int {
return 1
}
func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem {
return self.url! as QLPreviewItem
}
}
// Make editing available with Delegate
#available(iOS 13.0, *)
extension CustomVC: QLPreviewControllerDelegate {
func previewController(_ controller: QLPreviewController, editingModeFor previewItem: QLPreviewItem) -> QLPreviewItemEditingMode {
return .updateContents
}
func previewController(_ controller: QLPreviewController, didUpdateContentsOf previewItem: QLPreviewItem) {
print("UPDATE")
}
func previewController(_ controller: QLPreviewController, didSaveEditedCopyOf previewItem: QLPreviewItem, at modifiedContentsURL: URL) {
print("SAVED at \(modifiedContentsURL)")
}
}
The markup button will show automatically if you have implemented these functions in the delegate correctly.
You can also add more barButtonItems for this VC like normal with an extra navigationController, e.g. something like this in the editFile function:
let navController = UINavigationController(rootViewController: editor)
let customButton = UIBarButtonItem(image: UIImage(systemName: "yourImageName"), style: .plain, target: self, action: #selector(customButtonTapped(_:)))
let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(doneButtonTapped(_:)))
if var items = editor.navigationItem.rightBarButtonItems {
items.append(customButton)
editor.navigationItem.rightBarButtonItems = items
} else {
editor.navigationItem.rightBarButtonItems = [customButton]
}
editor.navigationItem.leftBarButtonItem = doneButton
viewController?.present(navController, animated: true, completion: nil)
self.navigationController = navController

How to print SFSafariViewController full web page?

I am opening a pdf file in SFSafariViewController. Now I want to print this PDF from SFSafariViewController.
But Share button of safari view controller does not have print option.
Please tell me how to add print functionality to SFSafariViewController.
You can custom activity.
extension ViewController: SFSafariViewControllerDelegate {
func safariViewController(_ controller: SFSafariViewController, activityItemsFor URL: URL, title: String?) -> [UIActivity] {
let acitivity = CustomActivity()
return [acitivity]
}
func printURL(url: URL) {
}
}
CustomActivity.swift
import Foundation
import UIKit
class CustomActivity: UIActivity {
override class var activityCategory: UIActivityCategory {
return .action
}
override var activityType: UIActivityType? {
return UIActivityType.print
}
override var activityTitle: String? {
return "Print"
}
override var activityImage: UIImage? {
return nil
}
override func canPerform(withActivityItems activityItems: [Any]) -> Bool {
return true
}
override func perform() {
// do something here
}
}

QLPreviewController Overlay

I'm creating a QLPreviewController:
func numberOfPreviewItemsInPreviewController(controller: QLPreviewController) -> Int {
return 1
}
func previewController(controller: QLPreviewController, previewItemAtIndex index: Int) -> QLPreviewItem {
let path = NSBundle.mainBundle().pathForResource("test", ofType: "pdf")
let url = NSURL.fileURLWithPath(path!)
return url
}
#IBAction func previewAction(sender: AnyObject) {
let preview = QLPreviewController()
preview.dataSource = self
self.presentViewController(preview, animated: true, completion: nil)
}
Now I want to add onto the QLPreviewController some kind of Overlay, at last a Label (that should always be seen).
Is there a way todo so?

Opening a PDF document when clicking a button

I am trying to create an app for my family restaurant in swift. I currently have a button that you click on that takes you too a webviewer page of our menu. I want to make the menu with in the app so it does not redirect to safari.
Basically what I want to do is click a button and it opens the menu pdf within the app instead safari.
The code that I use too open the PDF in a browser:
#IBAction func menu(sender: AnyObject) {
if let url = NSURL(string:"http://nebula.wsimg.com/db5e994c02db104ea89bdf6e59550490?AccessKeyId=895454CA4A1E296ED3E3&disposition=0&alloworigin=1") {
UIApplication.sharedApplication().openURL(url)
}
You can use QLPreviewController to preview your pdf but it needs to be a local resource or downloaded from the web prior to previewing:
Swift 3 or later
import UIKit
import QuickLook
class ViewController: UIViewController, QLPreviewControllerDataSource {
let preview = QLPreviewController()
func numberOfPreviewItems(in controller: QLPreviewController) -> Int {
return 1
}
func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem {
return Bundle.main.url(forResource: "menu", withExtension: "pdf")!
as QLPreviewItem
}
override func viewDidLoad() {
super.viewDidLoad()
// set preview data source
preview.dataSource = self
// set current item index (only one = 0)
preview.currentPreviewItemIndex = 0
}
#IBAction func showMenu(sender: UIButton) {
present(preview, animated: true) {
// code
}
}
}

Resources