Have you ever searched for a solution to open PDFs in your Xamarin Forms apps? There are a few third-party libraries available for this, but most require you to purchase a license. Of course, you can find solutions that are free, but less powerful, like this one. What most of these plugins have in common is that they offer you a way to display and manage pdf files and offer some form of customization to the plugin. But most of the time do not allow you embed the plugin’s components into your Xamarin Forms pages, or to fully control every aspect of your reader. Or, open directly the pdf in Xamarin forms pages.

What if you can’t pay a license and you want a pdf reader you control totally, one that you can use to open a pdf in Xamarin forms pages directly? One that you can manage bookmarks yourself, control navigation to a specific page, and make your own thumbnails if you like? This article is here to answer these questions.

If this post was useful to you, follow me on Twitter,  Github, Linkedinor like my Facebook page to stay updated.Follow me on social media and stay updated

Creating a Xamarin iOS PDF view

Since we are building a Xamarin Forms app, what we want to do is create a custom renderer for the iOS project. To learn more about custom renderers, you can follow this link. This custom renderer will natively be an instance of “PdfKit.PdfView”. This view is responsible for displaying pdf documents and permitting the user to interact with these documents.

First, in the shared project, we will create a PDFReaderView class. This class will be the shared view that abstracts our custom renderer. It will have the appropriate properties and Commands to open encrypted pdfs (PDFs that need password), Detect page changes, trigger the switch to a specific page from the code, and Load thumbnails in an asynchronous fashion so that the UI won’t freeze if we are loading thumbnails for a book with thousands of pages, etc.

Both the PDF Reader and the thumb view we will see later will inherit from the TextReader below. They have some properties in common, we will talk about these later.

Creating the Xamarin PDFView Custom renderer on iOS

As I mention earlier, we have to create a custom renderer, in this custom renderer, the first step will be to create the custom native control. Which in our case is “PdfKit.PdfView”.

Inside this custom renderer, we need to handle the opening of PDF files. For this, we create a function that takes the PDFView, the PDF’s path and its password. Then opens the PDF file. In this method, we create a PDFDocument object, that will give us information about the document such as its number of pages.

The next step is to handle property changes, when the password or the path to the PDF is set, we need to open the PDF and display it to users.

Generating thumbnails

The PDF kit has a control named: “PDFThumbnailView” that permits us to show a thumbnail for PDFs displayed in the PDF view. We Won’t use this control. I have tried using this control, and it it’s not malleable, and not user friendly at all. I think the iOS team should improve it.

Instead, we will create our own thumb view using Xamarin Form’s collection view, and a trick I’ll talk about later. Then we will combine both our thumb view and pdf view to display PDF in Xamarin Forms Pages.

The trick to display PDF thumbnails is, to use the instance of PDFDocument that we created when we opened the PDF. We then use the instance of this document to get each page of the PDF. For each page, we generate an image that represents its thumbnail. Then, we convert this native UIIMage image to a byte array that will be displayed above the PDF in Xamarin Forms Page.

We have to do all this asynchronously so that the UI does not block. Since we want this process to be non-blocking, while the page of the pdf is converted to thumbnail images, we need to display a list of empty pages to the user. We do this in the ViewModel when the “PageCountSetCommand” is fired. This is how we create our thumbnails,

We call this method when the PDF is opened in a new thread, to make it non-blocking.

Once the thumbnails are created, we fire the “ThumbNailsCreatedCommand” that will notify our view model that the thumbnails are ready to be displayed.  

The list of byte arrays of thumbnails added to an observable list of type “PDFThumbnailImageData” in the viewmodel. Here is what this class looks like.

To convert the byte array of image into an image source, we use a value converter. Here is what this converter looks like.

As mentioned above, the process of converting each page in a thumbnail can be blocking, and while it is taking place, we need to display a thumb view to the user, representing each page. To do this, we populate the observable collection of ThumbnailImageData with a page number when the “PageCountSetCommand” is called, which will be displayed to the user. This will function normally, except that no image will be displayed.

On our Xamarin Forms page, the thumbnail will be a collection view. Here is how it will be represented in XAML.

Here is the complete code for our PDF renderer.

To use this renderer in XAML, we instantiate it as follows:

Conclusion

As we saw in this article, we have almost everything at our disposal to open and manipulate a PDF in Xamarin Forms. We didn’t need any third-party library in the process. Next, we will see how to read PDF files on the android side of things. Stay tuned and don’t miss out. You might also like this article about creating a custom Skeleton loader in Xamarin Forms.

Follow me on social media and stay updated
%d bloggers like this: