Xamarin.Forms - Working With PDFView And Pinch Zoom

Introduction

 
Xamarin.Forms code runs on multiple platforms, each of which has its own filesystem. This means that reading and writing files are most easily done using the native file APIs on each platform. Alternatively, embedded resources are a simpler solution to distribute data files with an app.
 
Xamarin.Forms - Working With PDFView And Pinch Zoom
 
 

PDF Viewer

 
The Problem(Android)
 
PDFView doesn't support the default webview in android xamarin forms.
 
Solution
 
PDFView is the biggest issue in android webview. I solved this problem by using google drive viewer and google doc viewer there is another way to view pdf files using pdfjs. But pdfjs doesn't support pinch zoom.
 
https://github.com/mozilla/pdf.js/issues/2582
 
Note
The pdf URL must be an extension, PDF, and public.
 
Prerequisites
  • Visual Studio 2017 or later (Windows or Mac)

Setting up a Xamarin.Forms Project

 
Start by creating a new Xamarin.Forms project. You will learn more by going through the steps yourself.
 
Create a new or existing Xamarin forms (.Net standard) Project with Android and iOS Platform.
 
Choose the Mobile App (Xamarin. forms) project under C# and Mobile.
 
Name your app. You probably want your project and solution to use the same name as your app. Put it on your preferred location for projects and click "Create".
 
Now, select the blank app and target platforms - Android, iOS, and Windows (UWP).
 
Subsequently, go to the solution. In there, you get all the files and sources of your project (.NET Standard). Now, select the XAML page and double-click to open the MainPage.Xaml page.
 
You now have a basic Xamarin.Forms app. Click the Play button to try it out.
 
Create a Custom Webview
 
Here we're going to create a custom webview and inherit from the webview for custom rendering. I'm going to create two bindable properties: 
  1. Uri
  2. IsPDF
PDFView.cs
  1. public class PDFView: WebView  
  2.     {  
  3.         public static readonly BindableProperty UriProperty = BindableProperty.Create(propertyName: "Uri",  
  4.                 returnType: typeof(string),  
  5.                 declaringType: typeof(PDFView),  
  6.                 defaultValue: default(string));  
  7.   
  8.         public string Uri  
  9.         {  
  10.             get { return (string)GetValue(UriProperty); }  
  11.             set { SetValue(UriProperty, value); }  
  12.         }  
  13.   
  14.         public static readonly BindableProperty IsPDFProperty = BindableProperty.Create(propertyName: "IsPDF",  
  15.                 returnType: typeof(bool),  
  16.                 declaringType: typeof(PDFView),  
  17.                 defaultValue: default(bool));  
  18.   
  19.         public bool IsPDF  
  20.         {  
  21.             get { return (bool)GetValue(IsPDFProperty); }  
  22.             set { SetValue(IsPDFProperty, value); }  
  23.         }  
  24.   
  25.     }  
Android Implementation
 
Here, create a custom renderer for webview. In Android, the webview doesn't support pdf file preview. So I'm going to view the PDF files with Google Drive viewer.
 
Note
The URL must be of the extensions .PDF and public.
  1. https://drive.google.com/viewerng/viewer?embedded=true&url=" + "your url";  
Another Solution
  1. https://docs.google.com/gview?embedded=true&url=" + "your url";  
PDFViewRenderer.cs
  1. [assembly: ExportRenderer(typeof(PDFView), typeof(PDFViewRenderer))]  
  2. namespace PDFPOC.Droid  
  3. {  
  4.     public class PDFViewRenderer : WebViewRenderer  
  5.     {  
  6.         public PDFViewRenderer(Context context) : base(context)  
  7.         {  
  8.         }  
  9.         protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)  
  10.         {  
  11.             base.OnElementChanged(e);  
  12.   
  13.             if (e.NewElement != null)  
  14.             {  
  15.   
  16.   
  17.                 var pdfView = Element as PDFView;  
  18.                 Control.Settings.AllowUniversalAccessFromFileURLs = true;  
  19.                 if (pdfView.IsPDF)  
  20.                 {  
  21.                     var url = "https://drive.google.com/viewerng/viewer?embedded=true&url=" + pdfView.Uri;  
  22.                       
  23.                     Control.LoadUrl(url);  
  24.                 }  
  25.                 else  
  26.                 {  
  27.                     Control.LoadUrl(pdfView.Uri);  
  28.                 }  
  29.   
  30.             }  
  31.         }  
  32.     }  
  33. }  
iOS Implementation
 
Here, create a custom renderer for webview to load PDF files in webview.
 
PDFViewRenderer.cs
  1. [assembly: ExportRenderer(typeof(PDFView), typeof(PDFViewRenderer))]  
  2.   
  3. namespace PDFPOC.iOS  
  4. {  
  5.     public class PDFViewRenderer : WebViewRenderer  
  6.     {  
  7.         protected override void OnElementChanged(VisualElementChangedEventArgs e)  
  8.         {  
  9.             base.OnElementChanged(e);  
  10.   
  11.             if (NativeView != null && e.NewElement != null)  
  12.             {  
  13.                 var pdfControl = NativeView as UIWebView;  
  14.   
  15.                 if (pdfControl == null)  
  16.                     return;  
  17.   
  18.                 pdfControl.ScalesPageToFit = true;  
  19.             }  
  20.         }  
  21.     }  
  22. }  
Consuming the CustomWebview
 
Here, consume the Custom Webview in your XAML.
 
Add Namespace
  1. xmlns:controls="clr-namespace:PDFPOC.Controls"  
Add your Custom Webview
 
PDFView.xaml
  1. <?xml version="1.0" encoding="utf-8" ?>    
  2. <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"    
  3.              xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"    
  4.              xmlns:d="http://xamarin.com/schemas/2014/forms/design"    
  5.              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"    
  6.               xmlns:controls="clr-namespace:PDFPOC.Controls"    
  7.              mc:Ignorable="d"    
  8.              x:Class="PDFPOC.PDFViewer">    
  9.     <ContentPage.Content>    
  10.         <StackLayout BackgroundColor="Green"     
  11.                      HorizontalOptions="CenterAndExpand"     
  12.                      VerticalOptions="CenterAndExpand">    
  13.             <controls:PDFView x:Name="pdfView"      
  14.                               IsPDF="True"     
  15.                               HeightRequest="1000"    
  16.                               WidthRequest="1000"    
  17.                               VerticalOptions="FillAndExpand"  />    
  18.         </StackLayout>    
  19.     </ContentPage.Content>    
  20. </ContentPage>     
PDFView.xaml.cs
  1. public partial class PDFViewer : ContentPage  
  2.     {  
  3.         string url = "http://media.wuerth.com/stmedia/shop/catalogpages/LANG_it/1637048.pdf";  
  4.         public PDFViewer()  
  5.         {  
  6.             InitializeComponent();  
  7.   
  8.             if (Device.RuntimePlatform == Device.Android)  
  9.             {  
  10.                 pdfView.Uri = url;  
  11.                 pdfView.On<Android>().EnableZoomControls(true);  
  12.                 pdfView.On<Android>().DisplayZoomControls(false);  
  13.             }  
  14.   
  15.             else  
  16.                 pdfView.Source = url;  
  17.         }  
  18.   
  19.     }  
Click the "Play" button to try it out.

Android
 
You can test the Pinch zoom by the emulator. You can likewise use Shift + Ctrl + Left click and mouse movement.
 
Xamarin.Forms - Working With PDFView And Pinch Zoom
 
iOS
 
The simulator also supports pinch zoom use Alt + Left click and mouse move.
 
Xamarin.Forms - Working With PDFView And Pinch Zoom
 
Wow, it's working!
 
 
I hope you have understood how to implement a PDF view with pinch-zoom in Xamarin.Forms.
 
Thanks for reading. Please share your comments and feedback. Happy Coding :)