Displaying a common document in iOS is very simple and works very well… but only once you know how…
Being that Xamarin.iOS is just a wrap around the Native iOS API means that you must do it the Apple way.
In iOS there’s a controller named QLPreviewController and this is what you need to display documents. The quicklook supports a bunch of different formats and does it really well, these include iWork documents, Microsoft Office documents (Word, Excel, etc), Rich Text Format (RTF) documents, PDF file, Images, Text Files, CSV files.
The trick is that the QLPreviewController requires a preview item and a datasource. To setup your datasource you need to inherit from QLPreviewControllerDataSource as per the example below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | public class PreviewControllerDS : QLPreviewControllerDataSource { private QLPreviewItem _item; public PreviewControllerDS(QLPreviewItem item) { _item = item; } public override int PreviewItemCount (QLPreviewController controller) { return 1; } public override QLPreviewItem GetPreviewItem (QLPreviewController controller, int index) { return _item; } } |
The datasource requires a QLPreviewItem. Since you can access both Bundled File and Files Directly from the file-system I’ve created two different QLPreviewItems as per the example below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | public class QLPreviewItemFileSystem : QLPreviewItem { string _fileName, _filePath; public QLPreviewItemFileSystem(string fileName, string filePath) { _fileName = fileName; _filePath = filePath; } public override string ItemTitle { get { return _fileName; } } public override NSUrl ItemUrl { get { return NSUrl.FromFilename(_filePath); } } } public class QLPreviewItemBundle : QLPreviewItem { string _fileName, _filePath; public QLPreviewItemBundle(string fileName, string filePath) { _fileName = fileName; _filePath = filePath; } public override string ItemTitle { get { return _fileName; } } public override NSUrl ItemUrl { get { var documents = NSBundle.MainBundle.BundlePath; var lib = Path.Combine(documents, _filePath); var url = NSUrl.FromFilename(lib); return url; } } } |
Once you have that then putting it all together is simple.
1 2 3 4 | QLPreviewItemBundle prevItem = new QLPreviewItemBundle ("invoice.pdf", currentFilePath); QLPreviewController previewController = new QLPreviewController (); previewController.DataSource = new PreviewControllerDS (prevItem); NavigationController.PushViewController (previewController, true); |
Hi Michael.
I would like to use your code in a “DependencyService”, but I’m not able to compile it.
I would like to have something like
public class MyOpenFile : IOpenFile
{
public MyOpenFile ()
{
}
public void OpenFile(string filePath)
{
string filename = System.IO.Path.GetFileName (filePath);
string currentFilePath = System.IO.Path.GetDirectoryName (filePath);
QLPreviewItemBundle prevItem = new QLPreviewItemBundle (filename, currentFilePath);
QLPreviewController previewController = new QLPreviewController ();
previewController.DataSource = new PreviewControllerDS (prevItem);
NavigationController.PushViewController (previewController, true);
}
}
But I’ve an error in NavigationController.PushView…. row
How can I open documents in iOS using DependencyService and Xamarin Forms?
Thanks
Alessandro
Same question as Alessandro using FreshMvvm, is it this possible?