How to preview multiple PDF files in iOS similar to WhatsApp upload documents functionality?

771 Views Asked by At

I am integrating UIDocumentPickerViewController to show the local storage (File App) for browsing and selecting the PDF. Right now i am selecting a single PDF and previewing it by passing the URL to WKWebview which is working fine. But when i enable allowsMultipleSelection i am able to select the multiple files and getting multiple URLs

NSArray *types = @[(NSString*)kUTTypePDF];
//Create a object of document picker view and set the mode to Import
UIDocumentPickerViewController *docPicker = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:types inMode:UIDocumentPickerModeImport];
//Set the delegate
docPicker.delegate = self;
docPicker.allowsMultipleSelection = true; // Allows multiple selection.
//present the document picker
[self presentViewController:docPicker animated:YES completion:nil];

The delegate for getting multiple URLs is :

- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray <NSURL *>*)urls API_AVAILABLE(ios(11.0));

while previewing using WKWebView i am able to preview only one file as shown below:

But i want to preview both the selected files as WhatsApp does as shown below. Here i can swipe horizontally to preview the selected files

How to preview multiple files similar to WhatsApp? Please help me in this regard.

1

There are 1 best solutions below

0
On BEST ANSWER

Use a QLPreviewController; you'll need to import QuickLook. It's a view controller. You show it as a presented view controller or push it onto a navigation controller's stack.

In this example, I have somewhere in my Documents directory one or more PDF or text documents. I acquire a list of their URLs and present a preview for them (self.exts has been initialized to a set consisting of ["pdf", "txt"]):

self.docs = [URL]()
do {
    let fm = FileManager.default
    let docsurl = try fm.url(for:.documentDirectory, 
        in: .userDomainMask, appropriateFor: nil, create: false)
    let dir = fm.enumerator(at: docsurl, includingPropertiesForKeys: nil)!
    for case let f as URL in dir {
        if self.exts.contains(f.pathExtension) {
            if QLPreviewController.canPreview(f as QLPreviewItem) {
                self.docs.append(f)
            }
        }
    }
    guard self.docs.count > 0 else { return }
    let preview = QLPreviewController()
    preview.dataSource = self
    preview.currentPreviewItemIndex = 0
    self.present(preview, animated: true)
} catch {
    print(error)
}

You'll notice that I haven't told the QLPreviewController what documents to preview. That is the job of QLPreviewController's data source. In my code, I (self) am also the data source. I simply fetch the requested information from the list of URLs, which I previously saved into self.docs:

func numberOfPreviewItems(in controller: QLPreviewController) -> Int {
    return self.docs.count
}
func previewController(_ controller: QLPreviewController, 
    previewItemAt index: Int) -> QLPreviewItem {
        return self.docs[index] as QLPreviewItem
}

The second data source method requires us to return an object that adopts the QLPreviewItem protocol. URL does adopt this protocol.