Reputation: 17329
my spineLocationForInterfaceOrientation-method is not called; therefore, the spine is always on the left, but I would like to have it in the middle... what am I doing wrong?
if ([UIPageViewController class]) {
self.pageViewController = [[UIPageViewController alloc]
initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl
navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
self.pageViewController.view.backgroundColor = [UIColor redColor];
self.pageViewController.delegate = self;
NotesPageController *notesPageController = [[NotesPageController alloc]
initWithNibName:@"NotesPageController" bundle:nil];
NSArray *pageViewControllers = [NSArray arrayWithObjects:notesPageController, nil];
[self.pageViewController setViewControllers:pageViewControllers
direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:NULL];
self.pageViewController.dataSource = self;
[self addChildViewController:self.pageViewController];
[self.navigationController pushViewController:self.pageViewController animated:NO];
}
Thanks a lot!
Upvotes: 3
Views: 15631
Reputation: 994
Here's what worked for me. I used the default project which is generated by apple page view template. But when I was using it inside navigation controller it was not displaying the spine properly so had to modify the initialization code which can be called from viewDidLoad method.
- (void)initializePageViewController
{
int numberOfPagesPerScreen = 1;
if(UIInterfaceOrientationIsPortrait(self.interfaceOrientation))
numberOfPagesPerScreen = 1;
else
numberOfPagesPerScreen = 2;
// for two-page layouts, we'll need to specify the spine location
NSDictionary *pageViewOptions = nil;
if(numberOfPagesPerScreen == 2)
pageViewOptions = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInteger:UIPageViewControllerSpineLocationMid], UIPageViewControllerOptionSpineLocationKey, nil];
self.pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:pageViewOptions];
self.pageViewController.delegate = self;
NSMutableArray *pageViewControllers = [NSMutableArray array];
for(int pageViewIdx = 0; pageViewIdx < numberOfPagesPerScreen; pageViewIdx++) {
MyPageViewController *pageController = [self.modelController viewControllerAtIndex:pageViewIdx storyboard:self.storyboard];
[pageViewControllers addObject:pageController];
}
[self.pageViewController setViewControllers:pageViewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:NULL];
self.pageViewController.dataSource = self.modelController;
[self addChildViewController:self.pageViewController];
[self.view addSubview:self.pageViewController.view];
// Set the page view controller's bounds using an inset rect so that self's view is visible around the edges of the pages.
CGRect pageViewRect = self.view.bounds;
pageViewRect = CGRectInset(pageViewRect, 40.0, 40.0);
self.pageViewController.view.frame = pageViewRect;
[self.pageViewController didMoveToParentViewController:self];
// Add the page view controller's gesture recognizers to the book view controller's view so that the gestures are started more easily.
self.view.gestureRecognizers = self.pageViewController.gestureRecognizers;
}
Upvotes: 1
Reputation: 123
sample code for the answer provided by Totumus Maximus
NSDictionary *options = [NSDictionary dictionaryWithObject:
[NSNumber numberWithInteger:UIPageViewControllerSpineLocationMid]
forKey: UIPageViewControllerOptionSpineLocationKey];
self.pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:options];
Upvotes: 2
Reputation: 728
Do you have the view controller that contains the code above properly inserted into the view controller hierarchy? Start by setting UIWindow.rootViewController
and then call addChildViewController:
on every controller in the hierarchy. That's what was necessary for me to get the rotation forwarding and the spine function called when retrofitting an iOS4 app.
Edit: I've discovered there is more to it than this. Apple has made this class rather difficult to use. The problem is if you want to create the UIPageViewController at a different time from when you first call setViewControllers
. Most likely, the controller that contains the UIPageViewController is going to create it in init
or viewDidLoad
. But the true orientation isn't know at this point because apps are always started in portrait and then are sent rotation notifications if it's really in landscape. So, at the point most apps are going to create the UIPageViewController they don't know where the spine should be located.
Apple's sample calls setViewControllers
at the same time as initWithTransitionStyle
. This works in a trivial example like Apple's but most apps are probably going to dynamically load the content at a later time. If you haven't set any view controllers, then spineLocationForInterfaceOrientation
isn't called.
So now you're stuck if you've already created the UIPageViewController with initWithTransitionStyle
. You can't set the spine location and you have to insert exactly the correct number of view controllers for how you initialized the class when you didn't know the true orientation. If you set the wrong number of view controllers, it unhelpfully displays nothing on screen.
I see two possible solutions:
Always insert a dummy UIViewController right after calling initWithTransitionStyle
. Having a view controller in there will cause it to respond to rotation events and spineLocationForInterfaceOrientation
will be called.
Delay the create of the UIPageViewController until you are ready to set the actual content and the true orientation is known. This is what I chose.
Upvotes: 12
Reputation: 7573
Have you tried setting the spine property manually?
To set the spine location, wrap one of these constants in an NSNumber object and set it as the value for the UIPageViewControllerOptionSpineLocationKey key in the options dictionary passed to the initWithTransitionStyle:navigationOrientation:options: method.
Upvotes: 5