Currently I'm writing a Privacy policy for apps that I put in PDF format.
May I ask about how to open PDF file for Xamarin.Forms?
Any references Source Code?
It all depends a bit on the fact if your PDF file is hosted elsewhere or locally on the device.
If it is hosted online; the easiest way would be to just do a Device.OpenUri()
with the URI of the PDF file, but this would open an external browser.
If you want to incorporate it within your app you can create a page with a WebView
and navigate to the PDF in there. This should be pretty straight-forward.
Implement a page with a WebView
, I'm going to assume you use XAML.
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="DisplayPDF.WebViewPage"
Padding="0,20,0,0">
<ContentPage.Content>
<WebView Source="http://www.yoursite.com/your.pdf" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" />
</ContentPage.Content>
</ContentPage>
Local on the device there is no unified way to do this. One way is to implement it through showing it in a WebView
, which is basically the same as the WebView
above, but you need to create a CustomRenderer
for each platform you want to use. You can use the link provided by dylansturg as a reference.
Basically you implement the same page with a custom WebView
component.
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:DisplayPDF;assembly=DisplayPDF"
x:Class="DisplayPDF.WebViewPage"
Padding="0,20,0,0">
<ContentPage.Content>
<local:CustomWebView Uri="your.pdf" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" />
</ContentPage.Content>
</ContentPage>
Your custom WebView
will look like this:
public class CustomWebView : WebView
{
public static readonly BindableProperty UriProperty = BindableProperty.Create (propertyName:"Uri",
returnType:typeof(string),
declaringType:typeof(CustomWebView),
defaultValue:default(string));
public string Uri {
get { return (string)GetValue (UriProperty); }
set { SetValue (UriProperty, value); }
}
}
It's basically just a WebView
but we add a Uri
property to it.
Now if you want to implement it for iOS, create a CustomRenderer
in your platform project and implement it somewhat like this:
[assembly: ExportRenderer (typeof(CustomWebView), typeof(CustomWebViewRenderer))]
namespace DisplayPDF.iOS
{
public class CustomWebViewRenderer : ViewRenderer<CustomWebView, UIWebView>
{
protected override void OnElementChanged (ElementChangedEventArgs<CustomWebView> e)
{
base.OnElementChanged (e);
if (Control == null) {
SetNativeControl (new UIWebView ());
}
if (e.OldElement != null) {
// Cleanup
}
if (e.NewElement != null) {
var customWebView = Element as CustomWebView;
string fileName = Path.Combine (NSBundle.MainBundle.BundlePath, string.Format ("Content/{0}", WebUtility.UrlEncode (customWebView.Uri)));
Control.LoadRequest (new NSUrlRequest (new NSUrl (fileName, false)));
Control.ScalesPageToFit = true;
}
}
}
}
Here you see how we create a native UIWebView
and navigate it a file which is provided with our app. Note: the file should be in the Content file and marked as a BundleResource
. If you are to download the file (or new versions of the policy) make sure you adjust the path accordingly.
For Android it's a bit more work, you have to download the pdf.js library add it to you project under Assets. Make sure to check if the files are added to your repository as well. In my case the .js files where in my .gitignore
file by default.
Now create a custom renderer like this:
[assembly: ExportRenderer (typeof(CustomWebView), typeof(CustomWebViewRenderer))]
namespace DisplayPDF.Droid
{
public class CustomWebViewRenderer : WebViewRenderer
{
protected override void OnElementChanged (ElementChangedEventArgs<WebView> e)
{
base.OnElementChanged (e);
if (e.NewElement != null) {
var customWebView = Element as CustomWebView;
Control.Settings.AllowUniversalAccessFromFileURLs = true;
Control.LoadUrl (string.Format ("file:///android_asset/pdfjs/web/viewer.html?file={0}", string.Format ("file:///android_asset/Content/{0}", WebUtility.UrlEncode (customWebView.Uri))));
}
}
}
}
Notice how we navigate to the pdf.js library here and provide it with a query parameter to specify our PDF file. Again, this is when you provide the file with the app. Also this is only available from API 19 and up.
For Windows you should also use the pdf.js library.
As per Nikolai's kind response it seems there is also a lightweight pdf.js lib for mobile I didn't us it myself yet, but it seems better to use for mobile use.
Since this question still seems relevant I thought it would be nice to update it with a more thorough blog post I did on this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With