Embedding PDF View Controllers in iOS
PSPDFKit is designed to work well with UIKit’s container view controller API so that you can easily embed a
PDFViewController inside your custom container view controller implementation. The following steps will guide you through the setup.
First you need to make sure the
PDFViewController is properly added to your container view controller. A good guide on how to do this is Apple’s Implementing a Container View Controller. In our case, we want to add a PDF view controller fullscreen inside the container view controller. So our code to do that looks like this:
let containerController = ... // This is your custom container view controller. let pdfController = ... // This is the configured instance of `PDFViewController` that you want to add. containerController.addChild(pdfController) pdfController.view.frame = containerController.view.bounds // Make the `pdfController` fullscreen in your container controller. pdfController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight] // Ensure the `pdfController` resizes along with your container controller. containerController.view.addSubview(pdfController.view) pdfController.didMove(toParent: containerController)
UIViewController *containerController = ...; // This is your custom container view controller. PSPDFViewController *pdfController = ...; // This is the configured instance of `PSPDFViewController` that you want to add. [containerController addChildViewController:pdfController]; pdfController.view.frame = containerController.view.bounds; // Make the `pdfController` fullscreen in your container controller. pdfController.view.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight); // Ensure the `pdfController` resizes along with your container controller. [containerController.view addSubview:pdfController.view]; [pdfController didMoveToParentViewController:containerController];
For the most part, this information is from Figure 5-1 from the above-mentioned guide, but in addition, we make sure that the controller resizes properly whenever the container view controller’s view changes its bounds. If you are using auto layout inside your container view controller, you may need to alter the code to position and resize the PDF controller correctly.
Sometimes the size of the embedded
PDFViewController doesn’t match the size of the container controller. This is usually the case when the container controller adds some decorations around
PDFViewController (e.g. margins, custom navigation bars, or toolbars).
In such a case, you need to be aware that it’s the container’s responsibility to correctly define the size of its child controllers. Here are requirements you need to follow.
Make sure the correct frame is set on
PDFViewController’s view before you add it to your view hierarchy. Changing the size of
PDFViewController’s view during the appearance transition might cause UI issues.
If your container has a complex layout, it might be easier to add the
PDFViewController after your container lays out its subviews (
viewDidLayoutSubviews()), so that you’ll already know the correct frame for
Make sure your container controller implements the following:
func size(forChildContentContainer container: UIContentContainer, withParentContainerSize parentSize: CGSize) -> CGSize
- (CGSize)sizeForChildContentContainer:(id<UIContentContainer>)container withParentContainerSize:(CGSize)parentSize;
func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator)
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator;
PDFViewController uses this size to properly configure itself. Neglecting this might cause layout glitches and break automatic page mode.
If you integrate the
PDFViewController inside your custom view controller, you can still add your custom view controller inside a navigation controller afterward. However, there are a couple of things to keep in mind.
PDFViewController will no longer take care of the navigation bar, as the immediate child of the navigation controller is responsible for doing this. You can set
true in the
PDFConfiguration and we will do our best to update the navigation bar for you. However, this may not work well in all edge cases and we may require your help.
If you configure the
PDFViewController so that it should hide the navigation bar when the user taps on the screen (
PDFConfiguration.userInterfaceViewMode) and you are using opaque navigation bars (i.e. set
false), make sure to also set
true on your container view controller as well. Otherwise, the view of your container view controller will be resized every time the navigation bar changes its visibility state. This also means that the
PDFViewController will get resized in the same way, resulting in an up/down jump of the pages that are currently visible.
In general, when adding a custom container view controller between any kind of UIKit container view controllers (such as
UISplitViewController), make sure that the view controller hierarchy is set up correctly. The
PDFViewController’s parent view controller should always be your container view controller in such a case. You should not set the PDF view controller to become a child of the UIKit controller but rather embed it into your custom container view controller’s view hierarchy.
Also keep in mind that everything
PDFViewController would normally do when interacting with the default UIKit container view controllers (e.g. automatically managing navigation bar visibility), it no longer does when it’s embedded in a custom container view controller. From the perspective of the
PDFViewController, your custom container view controller is now responsible for the communication and proper handling of its parent UIKit container view controller.
If you want to look through more code, there are a couple of samples available in the Catalog under the ViewController Customization section.