Eightbot.MauiNativePdfView 1.0.4

Prefix Reserved
There is a newer version of this package available.
See the version list below for details.
dotnet add package Eightbot.MauiNativePdfView --version 1.0.4
                    
NuGet\Install-Package Eightbot.MauiNativePdfView -Version 1.0.4
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Eightbot.MauiNativePdfView" Version="1.0.4" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Eightbot.MauiNativePdfView" Version="1.0.4" />
                    
Directory.Packages.props
<PackageReference Include="Eightbot.MauiNativePdfView" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Eightbot.MauiNativePdfView --version 1.0.4
                    
#r "nuget: Eightbot.MauiNativePdfView, 1.0.4"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Eightbot.MauiNativePdfView@1.0.4
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Eightbot.MauiNativePdfView&version=1.0.4
                    
Install as a Cake Addin
#tool nuget:?package=Eightbot.MauiNativePdfView&version=1.0.4
                    
Install as a Cake Tool

<div align="center">

MauiNativePdfView

<img src="images/icon.svg" width="200" />

A high-performance, cross-platform PDF viewer for .NET MAUI

NuGet NuGet Downloads License: MIT .NET MAUI

Native PDF renderingZero web dependenciesFull feature parity

FeaturesInstallationQuick StartDocumentationExamples

</div>


🎯 Overview

MauiNativePdfView brings native PDF viewing capabilities to your .NET MAUI applications by wrapping platform-native controls. Unlike WebView-based solutions, this library provides true native performance with full access to platform-specific PDF features.

Why MauiNativePdfView?

  • 🚀 Native Performance - Uses PDFKit (iOS) and AhmerPdfium (Android) for optimal speed
  • 💪 Feature Complete - Comprehensive API with zoom, navigation, annotations, and events
  • 🎨 Consistent API - Write once, works on both iOS and Android
  • 📦 Zero Web Dependencies - No WebView, no JavaScript, pure native rendering
  • 🔧 Highly Configurable - Extensive properties for customization
  • 📱 Production Ready - Battle-tested with full annotation support

✨ Features

Core Functionality

  • Multiple PDF Sources - Load from files, URLs, streams, byte arrays, or embedded assets
  • Password Protection - Full support for encrypted PDFs
  • Zoom & Gestures - Pinch-to-zoom, double-tap zoom, with configurable min/max levels
  • Page Navigation - Swipe between pages, programmatic navigation, page events
  • Link Handling - Automatic detection and handling of internal/external links
  • Display Modes - Single page or continuous scrolling
  • Scroll Orientation - Vertical or horizontal page layout

Advanced Features

  • Annotation Rendering - Toggle PDF annotations on/off
  • Annotation Events - Tap detection with annotation details (iOS)
  • Quality Control - Antialiasing and rendering quality settings
  • Background Color - Customizable viewer background
  • Page Spacing - Adjustable spacing between pages
  • Event System - Comprehensive events for document lifecycle

Events

  • DocumentLoaded - Fires when PDF is loaded with page count and metadata
  • PageChanged - Current page and total page count updates
  • LinkTapped - User taps on a link with URI and destination
  • Tapped - General tap events with page coordinates
  • AnnotationTapped - Annotation tap with type, content, and bounds (iOS)
  • Rendered - Initial rendering complete
  • Error - Error handling with detailed messages

📦 Installation

NuGet Package Manager

dotnet add package MauiNativePdfView

Package Manager Console

Install-Package MauiNativePdfView

Requirements

  • .NET 9.0 or later
  • iOS 12.2+ (PDFKit)
  • Android 7.0+ (API 24+)

🚀 Quick Start

1. Add Namespace

xmlns:pdf="clr-namespace:MauiNativePdfView;assembly=MauiNativePdfView"

2. Basic XAML

<pdf:PdfView x:Name="pdfViewer"
             EnableZoom="True"
             EnableSwipe="True"
             DocumentLoaded="OnDocumentLoaded"
             PageChanged="OnPageChanged" />

3. Load a PDF

// From file
pdfViewer.Source = PdfSource.FromFile("/path/to/document.pdf");

// From URL
pdfViewer.Source = PdfSource.FromUri(new Uri("https://example.com/doc.pdf"));

// From embedded asset
pdfViewer.Source = PdfSource.FromAsset("sample.pdf");

// From stream
pdfViewer.Source = PdfSource.FromStream(myStream);

// From byte array
pdfViewer.Source = PdfSource.FromBytes(pdfBytes);

// With password
pdfViewer.Source = PdfSource.FromFile("/path/to/encrypted.pdf", "password");

4. Handle Events

private void OnDocumentLoaded(object sender, DocumentLoadedEventArgs e)
{
    Console.WriteLine($"Loaded: {e.PageCount} pages");
    Console.WriteLine($"Title: {e.Title}");
    Console.WriteLine($"Author: {e.Author}");
}

private void OnPageChanged(object sender, PageChangedEventArgs e)
{
    Console.WriteLine($"Page {e.PageIndex + 1} of {e.PageCount}");
}

📖 Documentation

PdfView Properties

Property Type Default Description
Source PdfSource null PDF source to display
EnableZoom bool true Enable pinch-to-zoom
EnableSwipe bool true Enable swipe gestures
EnableLinkNavigation bool true Enable clickable links
Zoom float 1.0f Current zoom level
MinZoom float 1.0f Minimum zoom level
MaxZoom float 3.0f Maximum zoom level
PageSpacing int 10 Spacing between pages (pixels)
FitPolicy FitPolicy Width How pages fit on screen
DisplayMode PdfDisplayMode SinglePageContinuous Page display mode
ScrollOrientation PdfScrollOrientation Vertical Scroll direction
DefaultPage int 0 Initial page (0-based)
EnableAntialiasing bool true Antialiasing (Android only)
UseBestQuality bool true Best quality rendering
BackgroundColor Color null Viewer background color
EnableAnnotationRendering bool true Show PDF annotations
CurrentPage int 0 Current page (readonly)
PageCount int 0 Total pages (readonly)

PdfSource Types

// File path
var source = PdfSource.FromFile(string filePath, string? password = null);

// URI/URL
var source = PdfSource.FromUri(Uri uri, string? password = null);

// Stream
var source = PdfSource.FromStream(Stream stream, string? password = null);

// Byte array
var source = PdfSource.FromBytes(byte[] data, string? password = null);

// Asset/Resource
var source = PdfSource.FromAsset(string assetName, string? password = null);

Enums

// How pages fit on screen
public enum FitPolicy
{
    Width,    // Fit to width
    Height,   // Fit to height
    Both      // Fit both dimensions
}

// Page display mode
public enum PdfDisplayMode
{
    SinglePage,           // One page at a time
    SinglePageContinuous  // Continuous scrolling
}

// Scroll direction
public enum PdfScrollOrientation
{
    Vertical,    // Scroll up/down
    Horizontal   // Scroll left/right
}

Methods

// Navigate to specific page (0-based)
pdfViewer.GoToPage(int pageIndex);

// Reload current document
pdfViewer.Reload();

💡 Examples

Complete PDF Viewer

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:pdf="clr-namespace:MauiNativePdfView;assembly=MauiNativePdfView"
             x:Class="MyApp.PdfPage">

    <Grid RowDefinitions="Auto,*,Auto">

        
        <HorizontalStackLayout Grid.Row="0" Padding="10" Spacing="10">
            <Button Text="◀" Clicked="OnPreviousPage" />
            <Button Text="▶" Clicked="OnNextPage" />
            <Button Text="Zoom In" Clicked="OnZoomIn" />
            <Button Text="Zoom Out" Clicked="OnZoomOut" />
        </HorizontalStackLayout>

        
        <pdf:PdfView x:Name="pdfViewer"
                     Grid.Row="1"
                     EnableZoom="True"
                     EnableSwipe="True"
                     EnableLinkNavigation="True"
                     EnableAnnotationRendering="True"
                     PageSpacing="10"
                     BackgroundColor="#F5F5F5"
                     DocumentLoaded="OnDocumentLoaded"
                     PageChanged="OnPageChanged"
                     LinkTapped="OnLinkTapped"
                     Error="OnError" />

        
        <Label x:Name="statusLabel"
               Grid.Row="2"
               Padding="10"
               HorizontalOptions="Center" />
    </Grid>

</ContentPage>
public partial class PdfPage : ContentPage
{
    public PdfPage()
    {
        InitializeComponent();
        pdfViewer.Source = PdfSource.FromAsset("sample.pdf");
    }

    private void OnDocumentLoaded(object sender, DocumentLoadedEventArgs e)
    {
        statusLabel.Text = $"Loaded: {e.PageCount} pages - {e.Title}";
    }

    private void OnPageChanged(object sender, PageChangedEventArgs e)
    {
        statusLabel.Text = $"Page {e.PageIndex + 1} of {e.PageCount}";
    }

    private void OnLinkTapped(object sender, LinkTappedEventArgs e)
    {
        if (e.Uri != null)
        {
            // Handle external link
            Launcher.OpenAsync(e.Uri);
            e.Handled = true;
        }
        else if (e.DestinationPage.HasValue)
        {
            // Internal link - handled automatically
        }
    }

    private void OnError(object sender, PdfErrorEventArgs e)
    {
        DisplayAlert("Error", e.Message, "OK");
    }

    private void OnPreviousPage(object sender, EventArgs e)
    {
        if (pdfViewer.CurrentPage > 0)
            pdfViewer.GoToPage(pdfViewer.CurrentPage - 1);
    }

    private void OnNextPage(object sender, EventArgs e)
    {
        if (pdfViewer.CurrentPage < pdfViewer.PageCount - 1)
            pdfViewer.GoToPage(pdfViewer.CurrentPage + 1);
    }

    private void OnZoomIn(object sender, EventArgs e)
    {
        pdfViewer.Zoom = Math.Min(pdfViewer.Zoom + 0.5f, pdfViewer.MaxZoom);
    }

    private void OnZoomOut(object sender, EventArgs e)
    {
        pdfViewer.Zoom = Math.Max(pdfViewer.Zoom - 0.5f, pdfViewer.MinZoom);
    }
}

MVVM Pattern

public class PdfViewModel : INotifyPropertyChanged
{
    private PdfSource _pdfSource;
    private int _currentPage;
    private int _pageCount;

    public PdfSource PdfSource
    {
        get => _pdfSource;
        set => SetProperty(ref _pdfSource, value);
    }

    public int CurrentPage
    {
        get => _currentPage;
        set => SetProperty(ref _currentPage, value);
    }

    public int PageCount
    {
        get => _pageCount;
        set => SetProperty(ref _pageCount, value);
    }

    public Command LoadPdfCommand { get; }
    public Command<int> GoToPageCommand { get; }

    public PdfViewModel()
    {
        LoadPdfCommand = new Command(LoadPdf);
        GoToPageCommand = new Command<int>(GoToPage);
    }

    private void LoadPdf()
    {
        PdfSource = PdfSource.FromAsset("document.pdf");
    }

    private void GoToPage(int pageIndex)
    {
        // Page navigation handled by binding
    }
}
<pdf:PdfView Source="{Binding PdfSource}"
             CurrentPage="{Binding CurrentPage}"
             PageCount="{Binding PageCount}" />

Password-Protected PDFs

try
{
    pdfViewer.Source = PdfSource.FromFile("encrypted.pdf", "mypassword");
}
catch (Exception ex)
{
    // Handle incorrect password
    await DisplayAlert("Error", "Invalid password", "OK");
}

Annotation Handling (iOS)

private void OnAnnotationTapped(object sender, AnnotationTappedEventArgs e)
{
    Console.WriteLine($"Annotation on page {e.PageIndex + 1}");
    Console.WriteLine($"Type: {e.AnnotationType}");
    Console.WriteLine($"Contents: {e.Contents}");
    Console.WriteLine($"Bounds: {e.Bounds}");

    // Prevent default behavior
    e.Handled = true;
}

🏗️ Architecture

┌─────────────────────────────────────┐
│     .NET MAUI Application           │
└─────────────┬───────────────────────┘
              │
┌─────────────▼───────────────────────┐
│      MauiNativePdfView              │
│  ┌────────────────────────────────┐ │
│  │   PdfView (MAUI Control)       │ │
│  │   - Bindable Properties        │ │
│  │   - Event Handlers             │ │
│  │   - Platform Handlers          │ │
│  └────────────────────────────────┘ │
└─────────────┬───────────────────────┘
              │
      ┌───────┴────────┐
      │                │
┌─────▼──────┐   ┌────▼───────┐
│  Android   │   │    iOS     │
│  Handler   │   │  Handler   │
└─────┬──────┘   └────┬───────┘
      │               │
┌─────▼──────┐   ┌────▼───────┐
│AhmerPdfium │   │  PDFKit    │
│ (Native)   │   │ (Native)   │
└────────────┘   └────────────┘

🔧 Platform Details

iOS (PDFKit)

  • Framework: Apple's native PDFKit
  • Version: iOS 12.2+
  • Features: Full annotation support, smooth rendering
  • Size: 0 KB (system framework)

Android (AhmerPdfium)

  • Library: AhmerPdfium by Ahmer Afzal
  • Base: Enhanced fork of AndroidPdfViewer
  • Version: 2.0.1 (viewer) + 1.9.2 (pdfium)
  • Features: 16KB page size support, reliable rendering
  • Size: ~16MB (native libraries for all architectures)
  • Note: Annotation tap events not supported by library

📊 Performance

  • Memory Efficient: Native rendering engines handle memory management
  • Fast Loading: Platform-optimized PDF parsing
  • Smooth Scrolling: Hardware-accelerated rendering
  • Large Files: Tested with 100+ page documents

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

Building from Source

git clone https://github.com/yourusername/MauiNativePdfView.git
cd MauiNativePdfView
dotnet restore
dotnet build

Running Tests

cd samples/MauiPdfViewerSample
dotnet build

📝 Changelog

See FEATURE_ENHANCEMENT_PLAN.md for detailed implementation history and feature roadmap.

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

Third-Party Licenses

  • AhmerPdfium: Apache License 2.0
  • PDFKit: Apple System Framework

🙏 Acknowledgments

  • Ahmer Afzal - AhmerPdfium library maintainer
  • barteksc - Original AndroidPdfViewer
  • Apple - PDFKit framework
  • .NET MAUI Team - Excellent framework

💬 Support

⭐ Show Your Support

If you find this library helpful, please give it a star! ⭐


<div align="center">

Made with ❤️ for the .NET MAUI community

⬆ Back to Top

</div>

Product Compatible and additional computed target framework versions.
.NET net9.0-android35.0 is compatible.  net9.0-ios18.0 is compatible.  net10.0-android was computed.  net10.0-ios was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.8 2,693 4/13/2026
1.0.7 2,022 1/9/2026
1.0.6 667 12/5/2025
1.0.5 221 11/26/2025
1.0.4 236 11/25/2025