UIPageviewController using Storyboard crash - ios

I'm gonna make a tutorial page using UIPageViewController.
But crash happened. I couldn't find the point occurring crash.
I'm trying to use UIPageViwController directly, not using in UIViewController.
dataSource works. but when trying to call [self setViewControllers:#[pageZero] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil];
, an error occurred like the below.
UserGuidePageViewController is linked to UIPagveViewController Frame in starboard.
Following is Header
#import <UIKit/UIKit.h>
#interface UserGuidePageViewController : UIPageViewController <UIPageViewControllerDataSource> {
}
#end
Following is code
#import "UserGuidePageViewController.h"
#import "UserGuideViewController.h"
#interface UserGuidePageViewController () {
}
#property (nonatomic, retain) NSArray *array;
#end
#implementation UserGuidePageViewController
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
self.dataSource = self;
}
return self;
}
- (UserGuideViewController *)userGuideViewForPageIndex:(NSUInteger)pageIndex
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UserGuideViewController *targetViewController = [storyboard instantiateViewControllerWithIdentifier:#"UserGuideViewController"];
return targetViewController;
}
- (void)viewDidLoad
{
[super viewDidLoad];
UserGuideViewController *pageZero = [self userGuideViewForPageIndex:0];
[self setViewControllers:#[pageZero] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil];
--> Crash happened here!!!
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Page View Controller Data Source
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
NSUInteger index = [(UserGuideViewController *)viewController pageIndex];
return [self userGuideViewForPageIndex:(index - 1)];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
NSUInteger index = [(UserGuideViewController *)viewController pageIndex];
return [self userGuideViewForPageIndex:(index + 1)];
}
- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController
{
// The number of items reflected in the page indicator.
return 1;
}
- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController
{
// The selected item reflected in the page indicator.
return 0;
}
Error is following.
*** Assertion failure in -[_UIQueuingScrollView setView:direction:animated:completion:], /SourceCache/UIKit/UIKit-2903.23/_UIQueuingScrollView.m:671
2013-12-18 15:23:35.779 Natural Calendar[4497:60b] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid parameter not satisfying: view'
*** First throw call stack:
(0x30ef6f4b 0x3b6d36af 0x30ef6e25 0x3189efe3 0x33ba3321 0x33b382eb 0x33b38407 0xf4715 0x3366e37b 0x3366e139 0xf0c45 0x1062d9 0x1106c3 0x3369e713 0x3369e6b3 0x3369e691 0x3368a11f 0x3369e107 0x3369ddd9 0x33698e65 0x3366e79d 0x3366cfa3 0x30ec2183 0x30ec1653 0x30ebfe47 0x30e2ac27 0x30e2aa0b 0x35b0b283 0x336ce049 0xecd09 0x3bbdbab7)
libc++abi.dylib: terminating with uncaught exception of type NSException
Actually, I changed into Xcode template style.
But this error is also occurred.
- (void)viewDidLoad
{
[super viewDidLoad];
_pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
[_pageViewController setDataSource:self];
UserGuideViewController *pageZero = [self userGuideViewForPageIndex:0];
[_pageViewController setViewControllers:#[pageZero] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil];
[self addChildViewController:_pageViewController];
[self.view addSubview:[_pageViewController view]];
CGRect pageViewRect = self.view.bounds;
//pageViewRect = CGRectInset(pageViewRect, 40.0, 40.0);
_pageViewController.view.frame = pageViewRect;
[_pageViewController didMoveToParentViewController:self];
}
I don't know what's problem. When choosing UIPageViewControllerTransitionStyleScroll, the error occurred. When choosing UIPageViewControllerTransitionStylePageCurl, the error is not happened.

#interface UserGuidePageViewController : UIPageViewController <UIPageViewControllerDataSource> {
chnge this line with
#interface UserGuidePageViewController : UIViewController <UIPageViewControllerDataSource> {
Means you can use UIViewcontroller for this
see this link for reference.
and this another link which is used storyboard.

I found loadView() { } declared at page ContentViewController. However loadView() remains empty without calling [super loadView];. As a result from this, the view would remain nil.
Now it appears to work after the removal of the method, loadView().

Related

Manually switching views in UIPageViewController causes exception

I have a UIPageViewController that displays two UIViewControllers and allows the user to swipe between the two. I implemented a button that allows the user to manually switch between the two. The code to execute this is as follows:
[self setViewControllers:#[[self.storyboard instantiateViewControllerWithIdentifier:#"PlayersViewController"]] direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:^(BOOL completion){}];
Unfortunately, every time I press the button, I get an exception that says:
* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* -[__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object from objects[0]'
I call the method from my custom class that extends the UIPageViewControllerDelegate.
Any help would be much appreciated!
**Edit:
Here are relevant portions of my custom class:
- (void)viewDidLoad
{
[super viewDidLoad];
self.dataSource = self;
gvc = [[GamesViewController alloc] init];
pvc = [[PlayersViewController alloc] init];
[self setViewControllers:#[[self.storyboard instantiateViewControllerWithIdentifier:#"GamesViewController"]] direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
}
- (void) slidepage
{
[self setViewControllers:#[[self.storyboard instantiateViewControllerWithIdentifier:#"PlayersViewController"]] direction:UIPageViewControllerNavigationDirectionReverse animated:NO completion:^(BOOL completion){NSLog(#"hihi");}];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
if ([viewController isKindOfClass:[GamesViewController class]])
return nil;
return [self.storyboard instantiateViewControllerWithIdentifier:#"GamesViewController"];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
if ([viewController isKindOfClass:[PlayersViewController class]])
return nil;
return [self.storyboard instantiateViewControllerWithIdentifier:#"PlayersViewController"];
}
It seems that
[self.storyboard instantiateViewControllerWithIdentifier:#"PlayersViewController"]
returns nil. This would mean that either self.storyboard is nil or the storyboard can't find a view controller for the given identifier.

how to show spine in uipageviewcontroller?

I am creating a simple UIPageViewController with just two pages, how do I show the spine? Currently there is nothing in the middle. Also the outside borders are missing.
This is the code for UIPageViewController
//
// PageViewController.m
// pageuiviewproject
//
//
#import "PageViewController.h"
#import "contentViewController.h"
#import <QuartzCore/QuartzCore.h>
#interface PageViewController ()
#property (nonatomic, strong) UIPageViewController *pageViewController;
#end
#implementation PageViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
self.pageViewController.delegate = self;
self.pageViewController.dataSource = self;
NSArray *viewControllers = [NSArray arrayWithObject:[[contentViewController alloc]init]];
[self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil];
[self addChildViewController:self.pageViewController];
[self.view addSubview:self.pageViewController.view];
[self.pageViewController didMoveToParentViewController:self];
self.pageViewController.view.layer.borderColor = [UIColor blackColor].CGColor;
self.pageViewController.view.layer.borderWidth = 3.0f;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - UIPageViewController delegate methods
-(UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController{
return [[contentViewController alloc] init];
}
-(UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController{
return [[contentViewController alloc] init];
}
-(UIPageViewControllerSpineLocation)pageViewController:(UIPageViewController *)pageViewController spineLocationForInterfaceOrientation:(UIInterfaceOrientation)orientation{
NSArray *viewControllers = [NSArray arrayWithObjects:[[contentViewController alloc] init], [[contentViewController alloc] init], nil];
[self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:NULL];
self.pageViewController.doubleSided = YES;
return UIPageViewControllerSpineLocationMid;
}
#end
The contentViewController is currently empty. This is what it looks like in simulator ...image
I want to create the following look mosaic app look. Is this a custom look? I was hoping this would be possible by setting UIPageViewController properties.
UIPageViewController does not provide any "look" at all. It's just a way of showing successive view controller's views. What you put in those views, or what you show behind/around/in front of the page view controller's view, is up to you. You want a book, draw a book.

UIPageViewController doesn't change page

I have a view controller implementing UIPageViewControllerDataSource delegate, and it contains a UIPageViewController.
My issue is that, after 3 hours of tutorials and reading, I still don't understand why the UIPageController reacts to swipe by moving it's content, but it doesn't change the page if the scroll is enough. It's always stuck on the first page.
So this is my .h file
#import <UIKit/UIKit.h>
#interface BreathePageViewController : UIViewController <UIPageViewControllerDataSource>
#property (strong, nonatomic) UIPageViewController *pageController;
#end
And this is my .m file
#import "BreathePageViewController.h"
#import "FirstViewController.h"
#import "SecondViewController.h.h"
#interface BreathePageViewController () {
NSArray *pageViewControllerScreens;
FirstViewController *firstViewController;
SecondViewController *secondViewController;
int pageIndex;
}
#end
#implementation BreathePageViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
pageIndex = 0;
self.pageController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
self.pageController.dataSource = self;
[[self.pageController view] setFrame:[[self view] bounds]];
[self.pageController setViewControllers:#[firstViewController] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil];
[self.view addSubview:self.pageController.view];
[self addChildViewController:self.pageController];
[[self view] addSubview:[self.pageController view]];
[self.pageController didMoveToParentViewController:self];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController {
if (pageIndex == 0) {
return nil;
}
pageIndex--;
return [self viewControllerAtIndex:pageIndex];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController {
if (pageIndex == 2) {
return nil;
}
pageIndex++;
return [self viewControllerAtIndex:pageIndex];
}
- (UIViewController *)viewControllerAtIndex:(NSUInteger)index {
UIViewController *vc;
if (pageIndex == 0 ) {
vc = [[FirstViewController alloc] init];
}
else if (pageIndex == 1) {
vc = [[SecondViewController alloc] init];
}
return vc;
}
- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController {
return 2;
}
- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController {
return 0;
}
#end
Now the strange stuff is that the pageViewController:viewControllerAfterViewController is never called.
Can someone help me out?
Thank you
After a night of sleep, I am going to to reply my own question.
I don't know why (any comment appreciated), but the problem was not on that view controller, but it was in the one I was creating it in.
In the parent view controller I was building the UIPageViewController like that:
BreathePageViewController *pageController = [[BreathePageViewController alloc] init];
[pageController.view setFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
[self.view addSubview:pageController.view];
And now I tried to move the declaration of pageViewController as an iVar. And it works.
Hope to help someone else

How to implement UIPageViewController with a UIScrollView?

I took the Photo Scroller example from Apple's website and tried to implement my own Album by copying the code. Now, the UIScrollView is not visible. How do I make it appear?
The only code change that I made was in creating the UIPageViewController. In my case, it's a UIViewController that is opening it and not the AppDelegate.
#implementation BasePhotoViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nil bundle:nibBundleOrNil];
if (self) {
// kick things off by making the first page
PhotoViewController *pageZero = [PhotoViewController photoViewControllerForPageIndex:0];
if (pageZero != nil)
{
// assign the first page to the pageViewController (our rootViewController)
//UIPageViewController *pageViewController = (UIPageViewController *) [[UIApplication sharedApplication] keyWindow].rootViewController;
UIPageViewController *pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:0 navigationOrientation:0 options:nil];
//UIPageViewController *pageViewController = (UIPageViewController *)self.parentViewController;
pageViewController.dataSource = self;
[pageViewController setViewControllers:#[pageZero]
direction:UIPageViewControllerNavigationDirectionForward
animated:NO
completion:NULL];
}
}
return self;
}
You are not adding the pageViewController's view as a subview of BasePhotoViewController's view. Your BasePhotoViewController class should look something like this. Note the code in viewDidLoad.
BasePhotoViewController.h:
#interface BasePhotoViewController : UIViewController <UIPageViewControllerDataSource>
#property (nonatomic, strong) UIPageViewController * pageViewController;
#end
BasePhotoViewController.m:
#import "BasePhotoViewController.h"
#import "PhotoViewController.h"
#implementation BasePhotoViewController
#synthesize pageViewController;
- (id)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (self) {
PhotoViewController *pageZero = [PhotoViewController photoViewControllerForPageIndex:0];
if (pageZero != nil)
{
self.pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:0
navigationOrientation:0
options:nil];
self.pageViewController.dataSource = self;
[self.pageViewController setViewControllers:#[pageZero]
direction:UIPageViewControllerNavigationDirectionForward
animated:NO
completion:NULL];
}
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self addChildViewController:self.pageViewController];
[self.view addSubview:self.pageViewController.view];
[self.pageViewController didMoveToParentViewController:self];
}
# pragma mark - UIPageViewControllerDataSource
- (UIViewController *)pageViewController:(UIPageViewController *)pvc viewControllerBeforeViewController:(PhotoViewController *)vc
{
NSUInteger index = vc.pageIndex;
return [PhotoViewController photoViewControllerForPageIndex:(index - 1)];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pvc viewControllerAfterViewController:(PhotoViewController *)vc
{
NSUInteger index = vc.pageIndex;
return [PhotoViewController photoViewControllerForPageIndex:(index + 1)];
}
#end
Note: I've initialised the UIPageViewController in initWithCoder: because Apple's Photo Scroller code uses a storyboard. I removed the UIPageViewController from the storyboard and created a BasePhotoViewController in its place. If you are not loading BasePhotoViewController from a storyboard, you should move the code in initWithCoder: to the appropriate initialiser.
EDIT: See this sample project on github.

Triggering the UIViewController connected to the UITabBarItem

Good day to you guys
I have an application that has a UITabBarController for tabbed-navigation... The view-controllers are mapped to their respective TabItems via a URL, just the same as that of Three20's TTNavigationSample App.
My problem is that inside a view controller of mine, i have a button that calls to another view controller which is also attached to a TabItem. When i trigger the button, the application throws an error. How can I resolve this?
In my TabBarController, i have this inside the viewDidLoad method:
-(void)viewDidLoad {
[self setTabURLs: [NSArrayWithObjects:
#"tt://bulletinBoard",
#"tt://contacts",
nil
]];
}
Sample .m file
#import "HabBarController.h"
#implementation TabBarController
- (void)viewDidLoad {
//these are variables like "tt/feed"
[self setTabURLs:[NSArray arrayWithObjects:
kAppFeedURLPath,
kAppHotURLPath,
kAppPostPhotoURLPath,
kAppGeneralActivityURLPath,
nil]];
}
- (UIViewController*)rootControllerForController:
(UIViewController*)controller {
if ([controller canContainControllers]) {
return controller;
} else {
UINavigationController* navController = [[[UINavigationController
alloc] init] autorelease];
[navController pushViewController:controller animated:NO];
return navController;
}
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self.tabBarController.navigationController setNavigationBarHidden:YES animated:NO];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)viewDidUnload {
[super viewDidUnload];
}
- (void)dealloc {
[super dealloc];
}
#end

Resources