88
99[ ![ NuGet] ( https://img.shields.io/nuget/v/Eightbot.MauiNativePdfView.svg )] ( https://www.nuget.org/packages/MauiNativePdfView/ )
1010[ ![ NuGet Downloads] ( https://img.shields.io/nuget/dt/Eightbot.MauiNativePdfView.svg )] ( https://www.nuget.org/packages/MauiNativePdfView/ )
11+
1112[ ![ License: MIT] ( https://img.shields.io/badge/License-MIT-blue.svg )] ( LICENSE )
1213[ ![ .NET] ( https://img.shields.io/badge/.NET-9.0-purple.svg )] ( https://dotnet.microsoft.com/download )
1314[ ![ MAUI] ( https://img.shields.io/badge/MAUI-Latest-green.svg )] ( https://github.com/dotnet/maui )
@@ -41,6 +42,7 @@ MauiNativePdfView brings native PDF viewing capabilities to your .NET MAUI appli
4142- ✅ ** Password Protection** - Full support for encrypted PDFs
4243- ✅ ** Zoom & Gestures** - Pinch-to-zoom, double-tap zoom, with configurable min/max levels
4344- ✅ ** Page Navigation** - Swipe between pages, programmatic navigation, page events
45+ - ✅ ** Link Interception** - Intercept and handle link taps before navigation (both platforms)
4446- ✅ ** Link Handling** - Automatic detection and handling of internal/external links
4547- ✅ ** Display Modes** - Single page or continuous scrolling
4648- ✅ ** Scroll Orientation** - Vertical or horizontal page layout
@@ -49,6 +51,7 @@ MauiNativePdfView brings native PDF viewing capabilities to your .NET MAUI appli
4951
5052- ✅ ** Annotation Rendering** - Toggle PDF annotations on/off
5153- ✅ ** Annotation Events** - Tap detection with annotation details (iOS)
54+ - ✅ ** Tap Gesture Control** - Enable/disable custom tap interception
5255- ✅ ** Quality Control** - Antialiasing and rendering quality settings
5356- ✅ ** Background Color** - Customizable viewer background
5457- ✅ ** Page Spacing** - Adjustable spacing between pages
@@ -58,8 +61,8 @@ MauiNativePdfView brings native PDF viewing capabilities to your .NET MAUI appli
5861
5962- ` DocumentLoaded ` - Fires when PDF is loaded with page count and metadata
6063- ` PageChanged ` - Current page and total page count updates
61- - ` LinkTapped ` - User taps on a link with URI and destination
62- - ` Tapped ` - General tap events with page coordinates
64+ - ` LinkTapped ` - Intercept link taps before navigation (set ` e.Handled = true ` to prevent)
65+ - ` Tapped ` - General tap events with page coordinates (requires ` EnableTapGestures = true ` )
6366- ` AnnotationTapped ` - Annotation tap with type, content, and bounds (iOS)
6467- ` Rendered ` - Initial rendering complete
6568- ` Error ` - Error handling with detailed messages
@@ -149,6 +152,7 @@ private void OnPageChanged(object sender, PageChangedEventArgs e)
149152| ` Source ` | ` PdfSource ` | ` null ` | PDF source to display |
150153| ` EnableZoom ` | ` bool ` | ` true ` | Enable pinch-to-zoom |
151154| ` EnableSwipe ` | ` bool ` | ` true ` | Enable swipe gestures |
155+ | ` EnableTapGestures ` | ` bool ` | ` false ` | Enable tap interception |
152156| ` EnableLinkNavigation ` | ` bool ` | ` true ` | Enable clickable links |
153157| ` Zoom ` | ` float ` | ` 1.0f ` | Current zoom level |
154158| ` MinZoom ` | ` float ` | ` 1.0f ` | Minimum zoom level |
@@ -287,13 +291,17 @@ public partial class PdfPage : ContentPage
287291 {
288292 if (e .Uri != null )
289293 {
290- // Handle external link
294+ // Intercept and handle external link yourself
295+ DisplayAlert (" Link Tapped" , $" Opening: {e .Uri }" , " OK" );
291296 Launcher .OpenAsync (e .Uri );
297+
298+ // Prevent default navigation
292299 e .Handled = true ;
293300 }
294301 else if (e .DestinationPage .HasValue )
295302 {
296- // Internal link - handled automatically
303+ // Internal link - allow default navigation
304+ // Or set e.Handled = true to prevent it
297305 }
298306 }
299307
@@ -394,6 +402,57 @@ catch (Exception ex)
394402}
395403```
396404
405+ ### Link Interception
406+
407+ Both iOS and Android support intercepting link taps before navigation occurs. This allows you to handle links yourself or prevent navigation entirely.
408+
409+ ``` csharp
410+ pdfViewer .LinkTapped += (sender , e ) =>
411+ {
412+ Console .WriteLine ($" Link tapped: {e .Uri }" );
413+
414+ if (e .Uri ? .Contains (" example.com" ) == true )
415+ {
416+ // Custom handling for specific domain
417+ DisplayAlert (" Info" , " This link is not allowed" , " OK" );
418+ e .Handled = true ; // Prevent navigation
419+ }
420+ else if (e .Uri != null )
421+ {
422+ // Log analytics before opening
423+ Analytics .TrackEvent (" PDF_Link_Clicked" , new Dictionary <string , string >
424+ {
425+ { " Uri" , e .Uri }
426+ });
427+
428+ // Allow default navigation (or handle manually)
429+ e .Handled = false ;
430+ }
431+ };
432+ ```
433+
434+ ** Platform Implementation:**
435+ - ** iOS** : Uses ` PdfViewDelegate.WillClickOnLink ` to intercept before navigation
436+ - ** Android** : Uses ` LinkHandler.HandleLinkEvent ` to intercept before navigation
437+
438+ ### Tap Gesture Handling
439+
440+ Enable custom tap detection with page coordinates:
441+
442+ ``` csharp
443+ pdfViewer .EnableTapGestures = true ;
444+
445+ pdfViewer .Tapped += (sender , e ) =>
446+ {
447+ Console .WriteLine ($" Tapped page {e .PageIndex } at ({e .X }, {e .Y })" );
448+
449+ // Add your custom tap handling logic
450+ // For example: show a custom menu, add annotations, etc.
451+ };
452+ ```
453+
454+ ** Note** : When ` EnableTapGestures = false ` (default), the PDF viewer uses native platform tap handling which is optimized for link detection.
455+
397456### Annotation Handling (iOS)
398457
399458``` csharp
@@ -404,11 +463,97 @@ private void OnAnnotationTapped(object sender, AnnotationTappedEventArgs e)
404463 Console .WriteLine ($" Contents: {e .Contents }" );
405464 Console .WriteLine ($" Bounds: {e .Bounds }" );
406465
407- // Prevent default behavior
466+ // Prevent default behavior if needed
408467 e .Handled = true ;
409468}
410469```
411470
471+ ** Note** : Annotation tap detection is only supported on iOS with PDFKit. Android's AhmerPdfium library does not expose annotation tap events.
472+
473+ ## 🎯 Common Scenarios
474+
475+ ### Restrict External Navigation
476+
477+ ``` csharp
478+ pdfViewer .LinkTapped += (sender , e ) =>
479+ {
480+ if (e .Uri != null && e .Uri .StartsWith (" http" ))
481+ {
482+ DisplayAlert (" Restricted" , " External links are not allowed" , " OK" );
483+ e .Handled = true ; // Block navigation
484+ }
485+ };
486+ ```
487+
488+ ### Track Link Clicks for Analytics
489+
490+ ``` csharp
491+ pdfViewer .LinkTapped += (sender , e ) =>
492+ {
493+ // Log the link click
494+ Analytics .TrackEvent (" PDF_Link_Clicked" , new Dictionary <string , string >
495+ {
496+ { " Document" , pdfViewer .Source ? .ToString () ?? " Unknown" },
497+ { " Link" , e .Uri ?? $" Page {e .DestinationPage }" },
498+ { " CurrentPage" , pdfViewer .CurrentPage .ToString () }
499+ });
500+
501+ // Allow normal navigation
502+ e .Handled = false ;
503+ };
504+ ```
505+
506+ ### Custom Link Handling with Confirmation
507+
508+ ``` csharp
509+ pdfViewer .LinkTapped += async (sender , e ) =>
510+ {
511+ if (e .Uri != null )
512+ {
513+ var result = await DisplayAlert (
514+ " Open Link?" ,
515+ $" Do you want to open {e .Uri }?" ,
516+ " Yes" ,
517+ " No"
518+ );
519+
520+ if (result )
521+ {
522+ await Launcher .OpenAsync (e .Uri );
523+ }
524+
525+ e .Handled = true ; // Prevent default navigation
526+ }
527+ };
528+ ```
529+
530+ ### Deep Link Handling
531+
532+ ``` csharp
533+ pdfViewer .LinkTapped += async (sender , e ) =>
534+ {
535+ if (e .Uri ? .StartsWith (" myapp://" ) == true )
536+ {
537+ // Handle custom URL scheme
538+ await Shell .Current .GoToAsync (e .Uri .Replace (" myapp://" , " " ));
539+ e .Handled = true ;
540+ }
541+ };
542+ ```
543+
544+ ### Disable All Link Navigation
545+
546+ ``` csharp
547+ // Simple approach
548+ pdfViewer .EnableLinkNavigation = false ;
549+
550+ // Or intercept all links
551+ pdfViewer .LinkTapped += (sender , e ) =>
552+ {
553+ e .Handled = true ; // Block all navigation
554+ };
555+ ```
556+
412557## 🏗️ Architecture
413558
414559```
@@ -445,15 +590,17 @@ private void OnAnnotationTapped(object sender, AnnotationTappedEventArgs e)
445590
446591- ** Framework** : Apple's native PDFKit
447592- ** Version** : iOS 12.2+
448- - ** Features** : Full annotation support, smooth rendering
593+ - ** Features** : Full annotation support, smooth rendering, link interception via ` PdfViewDelegate `
594+ - ** Link Handling** : Native ` WillClickOnLink ` delegate method
449595- ** Size** : 0 KB (system framework)
450596
451597### Android (AhmerPdfium)
452598
453599- ** Library** : [ AhmerPdfium] ( https://github.com/AhmerAfzal1/AhmerPdfium ) by Ahmer Afzal
454600- ** Base** : Enhanced fork of [ AndroidPdfViewer] ( https://github.com/barteksc/AndroidPdfViewer )
455601- ** Version** : 2.0.1 (viewer) + 1.9.2 (pdfium)
456- - ** Features** : 16KB page size support, reliable rendering
602+ - ** Features** : 16KB page size support, reliable rendering, link interception via ` LinkHandler `
603+ - ** Link Handling** : Custom ` ILinkHandler ` implementation
457604- ** Size** : ~ 16MB (native libraries for all architectures)
458605- ** Note** : Annotation tap events not supported by library
459606
@@ -471,7 +618,7 @@ Contributions are welcome! Please feel free to submit a Pull Request. For major
471618### Building from Source
472619
473620``` bash
474- git clone https://github.com/yourusername /MauiNativePdfView.git
621+ git clone https://github.com/TheEightBot /MauiNativePdfView.git
475622cd MauiNativePdfView
476623dotnet restore
477624dotnet build
@@ -484,9 +631,40 @@ cd samples/MauiPdfViewerSample
484631dotnet build
485632```
486633
487- ## 📝 Changelog
634+ ## ❓ Troubleshooting
635+
636+ ### Links Not Working on iOS
637+
638+ If links are not responding on iOS, ensure:
639+ 1 . ` EnableLinkNavigation = true ` (default)
640+ 2 . The PDF actually contains link annotations
641+ 3 . You're not setting ` e.Handled = true ` for all links in the ` LinkTapped ` event
642+
643+ ### Tapped Event Not Firing
644+
645+ The ` Tapped ` event requires:
646+ ``` csharp
647+ pdfViewer .EnableTapGestures = true ;
648+ ```
649+
650+ ** Note** : When ` EnableTapGestures = true ` , it may interfere with native link handling on some platforms. For link detection only, keep it ` false ` (default) and use the ` LinkTapped ` event.
651+
652+ ### LinkTapped Event Handler Not Called
653+
654+ Ensure you're subscribing to the event:
655+ ``` csharp
656+ pdfViewer .LinkTapped += OnLinkTapped ;
657+ ```
658+
659+ Or in XAML:
660+ ``` xml
661+ <pdf : PdfView LinkTapped =" OnLinkTapped" />
662+ ```
663+
664+ ### Android Annotation Events
665+
666+ Annotation tap events (` AnnotationTapped ` ) are ** only supported on iOS** . The Android AhmerPdfium library does not expose annotation-level tap detection. Use the ` Tapped ` event as an alternative for Android.
488667
489- See [ FEATURE_ENHANCEMENT_PLAN.md] ( FEATURE_ENHANCEMENT_PLAN.md ) for detailed implementation history and feature roadmap.
490668
491669## 📄 License
492670
@@ -506,9 +684,7 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
506684
507685## 💬 Support
508686
509- - 📖 [ Documentation] ( https://github.com/yourusername/MauiNativePdfView/wiki )
510- - 🐛 [ Issue Tracker] ( https://github.com/yourusername/MauiNativePdfView/issues )
511- - 💬 [ Discussions] ( https://github.com/yourusername/MauiNativePdfView/discussions )
687+ - 🐛 [ Issue Tracker] ( https://github.com/TheEightBot/MauiNativePdfView/issues )
512688
513689## ⭐ Show Your Support
514690
0 commit comments