COMING SOON: Fall 2024 Release

How to View a PDF in Xamarin.Forms Using Apryse

By Shirley Gong | 2018 Oct 23

Sanity Image
Read time

4 min

Xamarin.Forms provides the ability to build fully native Android, iOS and Universal Windows Platforms apps using C#. In this article, you will learn how to display a PDF in a fully featured document viewer and PDF editor with Xamarin.Forms using Apryse mobile SDK.

Before you get started, we recommend you have a look at Microsoft's comprehensive guide on Customizing a ContentPage. It is important that you understand how Xamarin renders the same page on different platforms using ContentPage, ExportRenderer and PageRenderer. For example, a page in Android is ViewGroup contained in a Fragment and a page in iOS is a UIViewController.

Complete sample code can be found here: Xamarin.Forms sample project

Create a Custom Renderer for the Xamarin Forms PDF Viewer

The rendering process can be taken advantage of to implement platform-specific customization by creating a custom renderer for a ContentPage on each platform. The process for doing this is as follows:

  1. Create a Xamarin.Forms page.
  2. Consume the page from Xamarin.Forms.
  3. Create the custom renderer for the page on each platform.

Creating the Xamarin.Forms Page

An unaltered ContentPage can be added to the shared Xamarin.Forms project, as shown in the following XAML code example:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="CustomRenderer.AdvancedViewerPage"
             Title="Advanced Viewer Page">
    <ContentPage.Content>
    </ContentPage.Content>
</ContentPage>

Similarly, the code-behind file for the ContentPage should also remain unaltered, as shown in the following code example:

public partial class AdvancedViewerPage : ContentPage
    {
        public AdvancedViewerPage()
        {
            // Document viewer contains toolbar, let's hide the global one
            NavigationPage.SetHasNavigationBar(this, false);
            InitializeComponent();
        }
    }

An instance of the AdvancedViewerPage will be used to display document viewer on each platform. Customization of the control will be carried out in the custom renderer, so no additional implementation is required in the AdvancedViewerPage class.

Consuming the Xamarin.Forms Page

The empty AdvancedViewerPage must be displayed by the Xamarin.Forms application. This occurs when a button on the MainPage instance is tapped, which in turn executes the OnOpenAdvancedViewerButtonClicked method, as shown in the following code example:

async void OnOpenAdvancedViewerButtonClicked(object sender, EventArgs e)
{
    await Navigation.PushAsync(new AdvancedViewerPage());
}

This code simply navigates to the AdvancedViewerPage, on which custom renderers will customize the page's appearance on each platform.

Creating the Page Renderer on each Platform

The AdvancedViewerPage instance is rendered by platform-specific AdvancedViewerPageRenderer classes, which all derive from the PageRenderer class for that platform. This results in each AdvancedViewerPage instance being rendered with document viewer, as shown in the following GIF.

iOS:

Image of AdvancedViewerPage instance being rendered with document viewer (iOS)

Android:

Image of AdvancedViewerPage instance being rendered with document viewer (Android))

Creating the Page Renderer on iOS

The following code example shows the page renderer for the iOS platform:

[assembly: ExportRenderer(typeof(AdvancedViewerPage), typeof(AdvancedViewerPageRenderer))]
namespace CustomRenderer.iOS
{
    public class AdvancedViewerPageRenderer : PageRenderer
    {
        private PTTabbedDocumentViewController mTabViewController;

        protected override void OnElementChanged(VisualElementChangedEventArgs e)
        {
            base.OnElementChanged(e);

            if (e.OldElement != null || Element == null)
            {
                return;
            }

            try
            {
                SetupUserInterface();
                SetupEventHandlers();
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(@"			ERROR: ", ex.Message);
            }
        }

        //...
    }
}

where the Xamarin iOS PDF viewer can be setup as follows:

void SetupUserInterface()
{
    mTabViewController = new PTTabbedDocumentViewController();
    UINavigationController navigationController = new UINavigationController(mTabViewController);

    AddChildViewController(navigationController);

    View.AddSubview(navigationController.View);

    navigationController.DidMoveToParentViewController(this);

    NSUrl fileURL = NSBundle.MainBundle.GetUrlForResource("sample", "pdf");

    mTabViewController.OpenDocumentWithURL(fileURL);
}

Creating the Page Renderer on Android

The following code example shows the page renderer for the Android platform:

[assembly: ExportRenderer(typeof(AdvancedViewerPage), typeof(AdvancedViewerPageRenderer))]
namespace CustomRenderer.Droid
{
    public class AdvancedViewerPageRenderer : PageRenderer
    {
        private DocumentView mDocumentView;

        public ViewerPageRenderer(Context context) : base(context)
        {
        }

        protected override void OnElementChanged(ElementChangedEventArgs<Page> e)
        {
            base.OnElementChanged(e);

            if (e.OldElement != null || Element == null)
            {
                return;
            }

            try
            {
                SetupUserInterface();
                SetupEventHandlers();
                AddView(view);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(@"			ERROR: ", ex.Message);
            }
        }

        //...
    }
}

where the Xamarin Android PDF viewer can be setup as follows:

void SetupUserInterface()
{
    activity = this.Context as Activity;
    view = activity.LayoutInflater.Inflate(Resource.Layout.AdvancedViewerLayout, this, false);

    mDocumentView = view.FindViewById<DocumentView>(Resource.Id.document_view);

    var context = this.Context;
    FragmentManager childManager = null;
    if (context is AppCompatActivity)
    {
        var activity = context as AppCompatActivity;
        var manager = activity.SupportFragmentManager;

        var fragments = manager.Fragments;
        if (fragments.Count > 0)
        {
            childManager = fragments[0].ChildFragmentManager;
        }
        if (childManager != null)
        {
            mDocumentView.OpenDocument(GetFile(), "", GetConfig(), childManager);
        }
    }
}

Check out the Xamarin forms sample for DocumentView class implementation.

And you are done!

View the full source code for this article.

Next steps

Looking for further guidance on using Xamarin Forms to open a PDF? Please get in touch. Our developers, who helped build our SDK from the ground up, would be happy to walk you through your options.

Sanity Image

Shirley Gong

Share this post

email
linkedIn
twitter