Is there any way I can use xamarin form to view a PDF file without using custom renderer.
-
1Try `Device.OpenUri()` and pass in a local URI of the PDF. This should open the PDF in the browser which is (hopefully) capable of viewing it. – Krumelur Jan 07 '15 at 13:36
-
I have tried `Device.OpenUri()` before and it works – Mario Galván Jan 07 '15 at 18:20
-
Thank you for your suggestion, but my app requirement is to open PDF file inside the app not in browser. – Sonu Jan 08 '15 at 06:25
-
1Then instantiate a WebView and use that to NavigateTo your local URI - you won't be switching apps, and your navigation stack will still work – Sten Petrov Jan 08 '15 at 15:01
-
OK. I got it. Thank you @StenPetrov and everyone for your suggestions. – Sonu Jan 12 '15 at 05:57
2 Answers
Android:
public void OpenPdf(string filePath)
{
Android.Net.Uri uri = Android.Net.Uri.Parse("file:///" + filePath);
Intent intent = new Intent(Intent.ActionView);
intent.SetDataAndType(uri, "application/pdf");
intent.SetFlags(ActivityFlags.ClearWhenTaskReset | ActivityFlags.NewTask);
try
{
Xamarin.Forms.Forms.Context.StartActivity(intent);
}
catch (Exception)
{
Toast.MakeText(Xamarin.Forms.Forms.Context, "No Application Available to View PDF", ToastLength.Short).Show();
}
}
iOS, a bit more complex and requiries some extra classes:
public void OpenPDF(string filePath)
{
FileInfo fi = new FileInfo(filePath);
QLPreviewController previewController = new QLPreviewController();
previewController.DataSource = new PDFPreviewControllerDataSource(fi.FullName, fi.Name);
UINavigationController controller = FindNavigationController();
if (controller != null)
controller.PresentViewController(previewController, true, null);
}
private UINavigationController FindNavigationController()
{
foreach (var window in UIApplication.SharedApplication.Windows)
{
if (window.RootViewController.NavigationController != null)
return window.RootViewController.NavigationController;
else
{
UINavigationController val = CheckSubs(window.RootViewController.ChildViewControllers);
if (val != null)
return val;
}
}
return null;
}
private UINavigationController CheckSubs(UIViewController[] controllers)
{
foreach (var controller in controllers)
{
if (controller.NavigationController != null)
return controller.NavigationController;
else
{
UINavigationController val = CheckSubs(controller.ChildViewControllers);
if (val != null)
return val;
}
}
return null;
}
public class PDFItem : QLPreviewItem
{
string title;
string uri;
public PDFItem(string title, string uri)
{
this.title = title;
this.uri = uri;
}
public override string ItemTitle
{
get { return title; }
}
public override NSUrl ItemUrl
{
get { return NSUrl.FromFilename(uri); }
}
}
public class PDFPreviewControllerDataSource : QLPreviewControllerDataSource
{
string url = "";
string filename = "";
public PDFPreviewControllerDataSource(string url, string filename)
{
this.url = url;
this.filename = filename;
}
public override QLPreviewItem GetPreviewItem(QLPreviewController controller, int index)
{
return new PDFItem(filename, url);
}
public override int PreviewItemCount(QLPreviewController controller)
{
return 1;
}
}
Use a dependency service to get them and call as needed, works very well for me. The PDFItem and PDFPreviewControllerDataSource classes are from a blog that i can't for the life of me remember the name of but they are not my work. The FindNavigationController may not be necessary in your case, it may be as simple as:
UISharedApplication.KeyWindow.PresentViewController
You can find the information here: https://forums.xamarin.com/discussion/25746/how-to-open-pdf-in-xamarin-forms

- 61,933
- 36
- 195
- 321
There is now a recipe covering this: https://developer.xamarin.com/recipes/cross-platform/xamarin-forms/controls/display-pdf/
Edit: Oops, the recipe does use Custom Renderers. It might still be useful if you can't get it working without a Custom Renderer though.

- 641
- 7
- 18