PSPDFDocumentViewLayout


@interface PSPDFDocumentViewLayout : UICollectionViewLayout

A document view layout controls how a document is visualized on screen. It controls where a spread (a set of pages) is placed on the screen and how scrolling and zooming behaves.

Subclassing

PSPDFDocumentViewLayout is an abstract base class meant for subclassing. You can either subclass PSPDFContinuousScrollingLayout or PSPDFScrollPerSpreadLayout if you want a layout similar to these two but only need a couple of tweaks. If you want to have more control but your layout still follows the general idea of a layout that scrolls in a single direction, either vertically or horizontally, PSPDFStackViewLayout, the superclass of the two aforementioned layouts, gives you a lot of control while covering the basics and a couple of convenience methods that make your life easier. This should be enough control for almost all designs. However if your design is very specific, we also give you the same base class all of our own layouts use: PSPDFDocumentViewLayout. With this layout you need to do everything on your own but there are almost no limitations on what to do with it.

Spreads

The main thing that a document view layout cares about is a spread; this is what it calculates the position of. A spread is a collection of pages that are always viewed together. If you have the most basic layout, a layout with its spread mode set to single, every spread corresponds to a single page in the document, which means the amount of spreads is equal to the amount of pages. However you can also have a double paged layout or a book layout. To convert between pages and spreads, PSPDFDocumentViewLayout provides you with helper methods. To make your layout work with all spread modes, it is important that you use these methods for conversion and, in case you want to implement your own spreading algorithms, override these methods and make them do the proper conversion, otherwise your layout may not work correctly in all cases.

UICollectionViewLayout

It is very important to keep in mind that a document view layout is based on UICollectionViewLayout and that this is what is used to calculate the position of a spread on the screen in the end. PSPDFDocumentViewLayout and especially its subclass PSPDFStackViewLayout offer you convenience methods that hide a lot of the complexity of collection views but depending on how the layout you are building should look, keep in mind that all the collection view layout methods can be used as well.

While the collection view layout works with index paths as its item identifying object, the document view layout does not need multiple levels of indexes. Each layout only needs to deal with one section. The important identifier for a document view layout is the spread index an item is representing. Therefore all the methods a PSPDFDocumentViewLayout and its subclasses offer refer to the spread index instead of an index path. For most layouts you will not come into contact with any of the index path based methods, but in case you do need them, PSPDFKit offers you two new methods on NSIndexPath to easily convert between index paths and spread indexes: +[NSIndexPath pspdf_indexPathForSpreadAtIndex:] and -[NSIndexPath pspdf_spreadIndex]. You should always use these methods to convert back and forth between spread indexes and index paths and not make any assumptions about how an index path maps to a spread index.

Additional APIs

Aside from the collection view layout, a document view layout also offers a few additional things that the document view controller and its views use to determine other behaviours, such as how zooming behaves (spreadBasedZooming), how spreads map to pages, and how the actual view hierarchy is positioned in relation to the view controller’s view (scrollViewFrameInsets).

Make sure to use the methods PSPDFDocumentViewLayout and its subclasses offer instead of just implementing everything by overriding the collection view layout methods. If you override one of the collection view layout methods, it is up to you to make sure that other methods such as spreadIndexForPageAtIndex:, pageRangeForSpreadAtIndex:, continuousSpreadIndexForContentOffset:, or contentOffsetForContinuousSpreadIndex: don’t return conflicting values or otherwise you might get unexpected results.

  • Unavailable

    Undocumented

    Declaration

    Objective-C

    PSPDF_INIT_WITH_CODER_UNAVAILABLE
  • The document that is laid out by the document view. Amongst other things it is used to determine the number and size of pages.

    Declaration

    Objective-C

    @property (readonly, nonatomic) PSPDFDocument *_Nonnull document;

    Swift

    var document: PSPDFDocument { get }
  • Spread based zooming means that each spread (a pair of pages in a double sided layout, or a single page otherwise) zooms individually. If this is turned off, all spreads will zoom together, making the whole document one giant zoomable canvas.

    Spread based zooming results in an experience similar to what the Photos app does, having it turned off is similar to what Safari does.

    Declaration

    Objective-C

    @property (assign, readwrite, nonatomic) BOOL spreadBasedZooming;

    Swift

    var spreadBasedZooming: Bool { get set }
  • The insets to apply to the scroll view’s frame.

    Subclasses can override this to inset the scroll view’s frame that is needed to layout spreads properly. If you override this, make sure to apply the additionalScrollViewFrameInsets or otherwise setting additional frame insets will have no effect.

    See

    -additionalScrollViewFrameInsets

    Declaration

    Objective-C

    @property (readonly, nonatomic) UIEdgeInsets scrollViewFrameInsets;

    Swift

    var scrollViewFrameInsets: UIEdgeInsets { get }
  • Additional insets to apply to the scroll view’s frame.

    Users of the layout can set insets here to customize the appearance of the layout.

    Defaults to UIEdgeInsetsZero.

    See

    -scrollViewFrameInsets

    Declaration

    Objective-C

    @property (assign, readwrite, nonatomic)
        UIEdgeInsets additionalScrollViewFrameInsets;

    Swift

    var additionalScrollViewFrameInsets: UIEdgeInsets { get set }
  • The continuous spread index at the passed in content offset.

    This method converts a given content offset to a continuous spread index.

    The continuous spread index represents the main visible spread as well as the scroll position of that page. A continuous spread index of 2.5 means that the spread index 2 is currently visible and already half way scrolled towards spread index 3.

    For most layouts, the above example would result in something where the second half of spread index 2 is visible and the first half of spread index 3.

    If you are not interested in the inter-spread offset, there are integer based methods availbale as well to read and modify the spread index.

    Warning

    When subclassing PSPDFDocumentViewLayout directly, you need to implement this method and do not call super. The base implementatio of this method throws an exception.

    Declaration

    Objective-C

    - (CGFloat)continuousSpreadIndexForContentOffset:(CGPoint)contentOffset;

    Swift

    func continuousSpreadIndex(forContentOffset contentOffset: CGPoint) -> CGFloat

    Parameters

    contentOffset

    The content offset whose continuous spread index should be calculated.

    Return Value

    The continuous spread index of the passed in content offset.

  • A content offset that has the passed in continuous spread index.

    This method is used to convert a given continuous spread index to a content offset.

    The continuous spread index represents the main visible spread as well as the scroll position of that page. A continuous spread index of 2.5 means that the spread index 2 is currently visible and already half way scrolled towards spread index 3.

    For most layouts, the above example would result in something where the second half of spread index 2 is visible and the first half of spread index 3.

    If you are not interested in the inter-spread offset, there are integer based methods available as well to read and modify the spread index.

    Warning

    When subclassing PSPDFDocumentViewLayout directly, you need to implement this method and do not call super. The base implementatio of this method throws an exception.

    Declaration

    Objective-C

    - (CGPoint)contentOffsetForContinuousSpreadIndex:(CGFloat)continuousSpreadIndex;

    Swift

    func contentOffset(forContinuousSpreadIndex continuousSpreadIndex: CGFloat) -> CGPoint

    Parameters

    continuousSpreadIndex

    The continuous spread index whose content offset should be calculated.

    Return Value

    The content offset of the passed in continuous spread index.

  • The total number of spreads in the document view.

    This is a computed property. The default implementation derives the number of spreads from converting the last page index to its spread index. Usually you do not need to override this method in a subclass, instead adopt the conversion methods as needed.

    See

    -pageIndexesForSpreadAtIndex:

    Declaration

    Objective-C

    @property (readonly, nonatomic) NSInteger numberOfSpreads;

    Swift

    var numberOfSpreads: Int { get }
  • Converts a given page index to the spread index of the spread representing it.

    Declaration

    Objective-C

    - (NSInteger)spreadIndexForPageAtIndex:(NSInteger)pageIndex;

    Swift

    func spreadIndexForPage(at pageIndex: Int) -> Int

    Parameters

    pageIndex

    The page index of the document.

    Return Value

    The spread index in the view hierarchy representing the given page index.

  • Converts a given spread index to the page range its spread represents.

    Usually a spread either represents one or two pages, but could represent more pages if a custom layout is used. The only constraint is that a spread can only represent adjacent pages.

    Declaration

    Objective-C

    - (NSRange)pageRangeForSpreadAtIndex:(NSInteger)spreadIndex;

    Swift

    func pageRangeForSpread(at spreadIndex: Int) -> NSRange

    Parameters

    spreadIndex

    The spread index of the view hierarchy.

    Return Value

    The range of pages in the document, represented by the given spread index.

  • Controls how pages are converted into spreads and back.

    This property is evaluated in the default implementations for spreadIndexForPageAtIndex: and pageRangeForSpreadAtIndex:. If you override these methods the value of this property may have no effect on the layout.

    Declaration

    Objective-C

    @property (readonly, nonatomic) PSPDFDocumentViewLayoutSpreadMode spreadMode;

    Swift

    var spreadMode: PSPDFDocumentViewLayoutSpreadMode { get }
  • Call this method if general view configuration properties such as spreadBasedZooming and scrollViewFrameInsets should be invalidated.

    Note

    While invalidateLayout handels the invalidation of the spreads positions, this method handles the overall configuration related to the document view.

    Declaration

    Objective-C

    - (void)invalidateConfiguration;

    Swift

    func invalidateConfiguration()
  • Configures the passed in scroll view to behave as desired by the layout.

    Declaration

    Objective-C

    - (void)configureScrollView:(nonnull UIScrollView *)scrollView;

    Swift

    func configureScrollView(_ scrollView: UIScrollView)

    Parameters

    scrollView

    The scroll view responsible for scrolling the content positioned by this layout.

  • Configures the passed in zoom view to behave as desired by the layout.

    Note

    Depending on the layout, you may receive this call either on a per spread basis with different zoom views when the spread in question becomes visible or you will receive this only once for the whole document, in which case the spread index will be NSNotFound.

    Declaration

    Objective-C

    - (void)configureZoomView:(nonnull UIScrollView *)zoomView
               forSpreadIndex:(NSInteger)spreadIndex;

    Swift

    func configureZoom(_ zoomView: UIScrollView, forSpreadIndex spreadIndex: Int)

    Parameters

    zoomView

    The scroll view responsible for zooming the given spread index.

    spreadIndex

    The spread index or NSNotFound if spreadBasedZooming is disabled and the zoom view is therefore controlling all spreads in the current document.

  • The area that would currently be shown by the document view if no zooming would be enabled.

    While this may sound complicated, this is used by the layouts to know the visible size of the collection view on default zoom scale.

    Declaration

    Objective-C

    @property (readonly, nonatomic) CGRect viewport;

    Swift

    var viewport: CGRect { get }
  • Asks the layout object if the new viewport requires a layout invalidation.

    The viewport defines the area that should be seen as the currently visible area from the layouts perspective. Due to implementation details the viewport might be different than the bounds of the collection view. In a custom layout you should implement and use this method in favor of shouldInvalidateLayoutForBoundsChange:.

    Declaration

    Objective-C

    - (BOOL)shouldInvalidateLayoutForViewportChange:(CGRect)newViewport;

    Swift

    func shouldInvalidateLayout(forViewportChange newViewport: CGRect) -> Bool

    Parameters

    newViewport

    The new viewport of the collection view.

    Return Value

    YES if the collection view requires a layout update or NO otherwise.

  • Returns an invalidation context that defines which parts of the layout should be invalidated due to a change of the viewport.

    The viewport defines the area that should be seen as the currently visible area from the layouts perspective. Due to implementation details the viewport might be different than the bounds of the collection view. In a custom layout you should implement and use this method in favor of invalidationContextForBoundsChange:.

    The default implementation creates an instance of the class provided by invalidationContextClass.

    Declaration

    Objective-C

    - (nonnull UICollectionViewLayoutInvalidationContext *)
    invalidationContextForViewportChange:(CGRect)newViewport;

    Swift

    func invalidationContext(forViewportChange newViewport: CGRect) -> UICollectionViewLayoutInvalidationContext

    Parameters

    newViewport

    The new viewport of the collection view.

    Return Value

    An invalidation context that describes the changes that need to be made. Do not return nil.

  • Undocumented

    Declaration

    Objective-C

    - (void)invalidateLayoutWithContext:(UICollectionViewLayoutInvalidationContext *)context NS_REQUIRES_SUPER;

    Swift

    func invalidateLayout(with context: UICollectionViewLayoutInvalidationContext)
  • Unavailable

    Undocumented

    Declaration

    Objective-C

    - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds NS_UNAVAILABLE;
  • Unavailable

    Undocumented

    Declaration

    Objective-C

    - (UICollectionViewLayoutInvalidationContext *)invalidationContextForBoundsChange:(CGRect)newBounds NS_UNAVAILABLE;
  • Creates a scroll per spread layout as provided by PSPDFScrollPerSpreadLayout.

    This is a layout that paginates from one spread to the next and does not stop at intermediate spread positions.

    Declaration

    Objective-C

    + (nonnull PSPDFScrollPerSpreadLayout *)scrollPerSpreadLayout;

    Swift

    class func scrollPerSpread() -> PSPDFScrollPerSpreadLayout

    Return Value

    A newly configured layout, ready to be used in a document view.

  • Creates a continuous scrollin layout as provided by PSPDFContinuousScrollingLayout.

    This is a layout that scrolls through spreads and pages continuously, whithout any prominent scroll positions. When scrolling in a horizontal direction, the spread mode is ignored and all spreads will always be treated as single spreads.

    Declaration

    Objective-C

    + (nonnull PSPDFContinuousScrollingLayout *)continuousScrollingLayout;

    Swift

    class func continuousScrolling() -> PSPDFContinuousScrollingLayout

    Return Value

    A newly configured layout, ready to be used in a document view.

  • Creates a page curl layout.

    This is a layout that looks similar to a book. The user can curl through pages. It shows either single or double spreads and changes the page binding according to the page binding option of the document.

    Declaration

    Objective-C

    + (nonnull PSPDFDocumentViewLayout *)pageCurlLayout;

    Swift

    class func pageCurl() -> PSPDFDocumentViewLayout

    Return Value

    A newly configured layout, ready to be used in a document view.