NSPageController Class Reference

Inherits from
Conforms to
Framework
/System/Library/Frameworks/AppKit.framework
Availability
Available in OS X v10.8 and later.
Declared in
NSPageController.h
Related sample code

Overview

The NSPageController class is used for controlling swipe navigation and animations between views or view content. It is useful for user interfaces which control navigating multiple pages as in a book or a web browser history.

Page controller inherits from the NSViewController class . You must assign the view property to a view in your view hierarchy. The NSPageController class does not vend a view. The NSPageController class does insert itself into the responder chain.

Conceptually, the page controller manages swiping between an array of pages, the arrangedObjects. Using the selectedIndex property, you can determine how many pages forward or backward the user may navigate.

Page Controller Modes

There are two modes that an NSPageController instance may operate in, history mode and book mode. The main difference between the two modes is that History mode expects pageController.view to be the content and Book mode expects pageController.view to be be a container for the content that you will supply by returning viewControllers in your delegate methods.

History Mode

History mode is designed to be the easiest way to create a history user interface. The page controller will manage the history (the arrangedObjects property), snapshots, and user navigation between pages in the history.

As the user navigates to new content, add to the history by calling navigateForwardToObject:. The page controller will remove any arrangedObjects after the selectedIndex and then add the object to the end of the arrangedObjects array and update the selectedIndex property. Just like navigating in a new direction in a web browser, all forward history is lost once the user starts navigating a new path. After returning from navigateForwardToObject: you are free to update the contents of pageController.view.

Delegate Method Invocation During History Mode Swiping

During swiping, the following optional delegate methods are called in the specified order:

The pageControllerWillStartLiveTransition: delegate method is invoked when the user starts a swipe action. This is the appropriate point at which to save information that you may need to restore, such as a page’s scrolled location.

Upon returning from the this delegate method, pageController.view is hidden. In it's place the page controller shows a private view hierarchy to animate previously taken snapshots of the page history. This allows the page controller to remain responsive to the user without any required action by your application. Next, if implemented, the pageController:didTransitionToObject: delegate method is invoked. This delegate method is called after a physically successful swipe, but before the animation has completed. The supplied object is the page the user navigated to – the new selectedIndex object in arrangedObjects. If background loading tasks need to be initiated this is the appropriate time to do so. However, do not block the main thread or the animation will stutter or pause.

Finally, the pageControllerDidEndLiveTransition: delegate method is invoked after the swipe and swipe animations are complete. You should any position settings or other display specific state stored in the pageControllerWillStartLiveTransition: implementation. The pageController.view is still hidden at this point and you must call completeTransition on the page controller instance to inform the instance to hide the private transition view and show pageController.view. Often you do this immediately, however, if your content is not ready you can call this at a later.

Book Mode (View Controller Mode)

Book mode is designed to give you more control over the swiping process and to facilitate more user interface designs than just history, although you can use book mode to create a history user interface.

In this mode, pageController.view is a container view and the content views are vended by view controller instances supplied by the delegate object.

To enable book mode, you must implement the following two methods in your delegate: pageController:identifierForObject: and pageController:viewControllerForIdentifier:.

The page controller instance caches the view controllers supplied for each identifier and only asks it's delegate to create more if one does not already exists in its cache. If you have different type of views you want to swipe in, then supply a different identifier for each type.

When needed, you will be asked to prepare a view controller instance with a page via the optional delegate method pageController:prepareViewController:withObject:. If you do not implement this method, then the representedObject of the view controller that would have been passed to this delegate method is set as the object.

The delegate will be asked to prepare a view controller with a nil object for each unique identifier it encounters. The NSPageController instance will use this to generate a default snapshot for that identifier.

When using the book mode, if pageController.view is layer backed, live layers are used during transition instead of snapshots.

Generally, when using book mode, the set of pages are known and it is your responsibility to set the arrangedObjects array property and initially selected page using the selectedIndex property.

Delegate Method Invocation During Book Mode Swiping

During swiping, the following optional delegate methods are called in the specified order:

The delegate method pageControllerWillStartLiveTransition: is invoked when the user starts a swipe action. As in history mode, this is the appropriate point at which to save information that you may need to restore, such as a page’s scrolled location.

After returning from the pageControllerWillStartLiveTransition: delegate method, the page controller takes a snapshot of the view in the specified selectedViewController and then removes it from pageController.view. The page controller replaces it with a private view hierarchy to animate previously taken snapshots. Unlike when building up a history, snapshots may not yet exist for the page being navigated to. In this case, a previously gathered default snapshot is used for that page's identifier. Regardless, if using a default snapshot or a previously gathered snapshot of actual contents, a view controller is prepared for the page being navigated to, and passed to the delegate. This viewController.view is then asked to draw on a background thread while swiping continues. Note that at this point the view does not reside within a window. Once the background threaded drawing completes, the initial snapshot is replaced with the newly generated snapshot.

Next the pageController:didTransitionToObject: delegate method is invoked after a physically successful swipe, but before the animation has completed. The supplied object is the page the user navigated to - the new object in the arrangedObjects array at the selectedIndex. Note that the page controller’s selectedViewController has not been updated yet. If you need to start some background loading tasks, now is the time to do it. Do not block the main thread or the animation will stutter or pause.

Finally the pageControllerDidEndLiveTransition: method is invoked after the swipe and swipe animations are complete. The selectedViewController.view is still detached at this point and you must call completeTransition on the page controller to hide the private transition view and update the selectedViewController. Often you do this immediately, however, if your content is not ready you can call this at a later.

Completing the Page Controller Transition

An NSPageController instance uses a private view hierarchy during swiping. To create a seamless transition to the new content, it is your responsibility to inform the page controller when you are ready to draw the new content. Ideally, the new content should match the snapshot so the user is none the wiser. You inform the page controller to complete the transition by calling completeTransition. If needed, a view controller is prepared and then the content view is shown (or added) to the view hierarchy and the private transition view is hidden.

During page controller initiated animations, pageControllerWillStartLiveTransition: and pageControllerDidEndLiveTransition: are invoked on the delegate. Generally during pageControllerDidEndLiveTransition: you will call completeTransition. Programatic animations via the animator proxy do not call the delegate methods and you are responsible for calling completeTransition when the animation completes.This is easily done via a completion handler on an NSAnimationContext grouping. For example:

 //To instantly change the selectedIndex:
  pageController.selectedIndex = newIndex;
 
  //To animate a selectedIndex change:
  [NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
    [[pageController animator] setSelectedIndex:newIndex];
  } completionHandler:^{
    [pageController completeTransition];
  }];

Tasks

Page Controller Items

Page Controller Navigation

Getting and Setting the Delegate

Transition Style

Completing Page Transition

Getting the View Controller

Properties

arrangedObjects

An array containing the objects displayed in the page controller’s view.

@property(copy) NSArray *arrangedObjects
Discussion

The delegate will be asked for snapshots as they are needed. Alternatively, you may never directly set this array and use the -navigateForwardToObject: method to create a history as the user navigates.

This property is key-value observing compliant.

Availability
  • Available in OS X v10.8 and later.
Declared In
NSPageController.h

delegate

The page controller’s delegate object.

@property(assign) id<NSPageControllerDelegate> delegate
Discussion

The delegate must conform to the NSPageControllerDelegate protocol.

Availability
  • Available in OS X v10.8 and later.
Declared In
NSPageController.h

selectedIndex

The currently selected object in the arranged objects array.

@property NSInteger selectedIndex
Discussion

To animate a transition to a new index, use the NSPageController class animator object.

This property is key-value observing compliant.

Availability
  • Available in OS X v10.8 and later.
Declared In
NSPageController.h

selectedViewController

The view controller associated with the selected object.. (read-only)

@property(retain, readonly) NSViewController *selectedViewController
Discussion

May be nil if not using view controllers.

This property is only relevant in book mode. See “Book Mode (View Controller Mode)” for details.

Availability
  • Available in OS X v10.8 and later.
Declared In
NSPageController.h

transitionStyle

The transition style the page controller uses when changing pages.

@property NSPageControllerTransitionStyle transitionStyle
Discussion

The possible values for the transition style are discussed in “NSPageControllerTransitionStyle.”

The default value is NSPageControllerTransitionStyleStackHistory.

Availability
  • Available in OS X v10.8 and later.
Declared In
NSPageController.h

Instance Methods

completeTransition

Invoked when the page transition is completed.

- (void)completeTransition
Discussion

See “Completing the Page Controller Transition” for a complete description.

Availability
  • Available in OS X v10.8 and later.
Related Sample Code
Declared In
NSPageController.h

navigateBack:

Navigates backwards in the page controller’s arranged objects array.

- (void)navigateBack:(id)sender
Parameters
sender

The sender.

Discussion

This method is typically invoked in response to a user interacting with a control, the sender.

This method is animated and invokes the delegate’s pageControllerWillStartLiveTransition: and pageControllerDidEndLiveTransition: methods.

Availability
  • Available in OS X v10.8 and later.
Declared In
NSPageController.h

navigateForward:

Navigates to the next object in the page controller’s arranged objects array, if appropriate.

- (void)navigateForward:(id)sender
Parameters
sender

The sender.

Discussion

This method is typically invoked in response to a user interacting with a control, the sender.

This method is animated and invokes the delegate’s pageControllerWillStartLiveTransition: and pageControllerDidEndLiveTransition: methods.

Availability
  • Available in OS X v10.8 and later.
Declared In
NSPageController.h

navigateForwardToObject:

Navigates to the specific object.

- (void)navigateForwardToObject:(id)object
Parameters
object

The object to display.

Discussion

Clears the arrangedObjects array after the selected index, adds the argument to that array, and sets the selectedIndex to the object’s index.

Availability
  • Available in OS X v10.8 and later.
Declared In
NSPageController.h

takeSelectedIndexFrom:

Navigates to the selected index, which is taken from the sender.

- (void)takeSelectedIndexFrom:(id)sender
Parameters
sender

The control that invoked the action.

Discussion

When invoked, this method causes the page controller’s view to display the object specified by the value taken from the sender control.

This method is animated and invokes the delegate’s pageControllerWillStartLiveTransition: and pageControllerDidEndLiveTransition: methods.

Availability
  • Available in OS X v10.8 and later.
Declared In
NSPageController.h

Constants

NSPageControllerTransitionStyle

These constants control the transition style of the page controller.

enum {
   NSPageControllerTransitionStyleStackHistory,
   NSPageControllerTransitionStyleStackBook,
   NSPageControllerTransitionStyleHorizontalStrip
}
typedef NSInteger NSPageControllerTransitionStyle;
Constants
NSPageControllerTransitionStyleStackHistory

Pages are stacked on top of each other. Pages animate out to the right to reveal the previous page. Next pages animate in from the right.

Available in OS X v10.8 and later.

Declared in NSPageController.h.

NSPageControllerTransitionStyleStackBook

Pages are stacked on top of each other. Pages animate out to the left to reveal the next page. Previous pages animate in from the left.

Available in OS X v10.8 and later.

Declared in NSPageController.h.

NSPageControllerTransitionStyleHorizontalStrip

Each page is laid out next to each other in one long horizontal strip

Available in OS X v10.8 and later.

Declared in NSPageController.h.

Discussion

These transition styles are independent of the delegate’s specification of book or history mode. It is perfectly reasonable to create a history style user interface using the book mode delegate methods. Simply set the transition style appropriately.