Reputation: 2777
I am trying to implement a UIPageViewController
. I have 4 separate viewControllers created and added to my storyboard. Now I want to scroll through it with a UIPageViewController
. This is what I do in code.
I made an modelArray an put all the VC in it :
self.modelArray = [[NSMutableArray alloc] init];
NSMutableArray *pageData = [[NSMutableArray alloc]init];
ViewOneViewController *viewOne = [self.storyboard instantiateViewControllerWithIdentifier:@"ViewOne"];
ViewTwoViewController *viewTwo = [self.storyboard instantiateViewControllerWithIdentifier:@"ViewTwo"];
ViewThreeViewController *viewThree = [self.storyboard instantiateViewControllerWithIdentifier:@"ViewThree"];
ViewFourViewController *viewFour = [self.storyboard instantiateViewControllerWithIdentifier:@"ViewFour"];
[pageData addObject:viewOne];
[pageData addObject:viewTwo];
[pageData addObject:viewThree];
[pageData addObject:viewFour];
self.modelArray = pageData;
Next setup the basics of the UIPageViewController
and set the Initial VC :
ViewOneViewController *cVC = [self.storyboard instantiateViewControllerWithIdentifier:@"ViewOne"];
NSArray *viewControllers = [NSArray arrayWithObject:cVC];
[self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
// Add the pageViewController as the childViewController
[self addChildViewController:self.pageViewController];
// Add the view of pageViewController to the currentView
[self.view addSubview:self.pageViewController.view];
// Call didMoveToParentViewController: of the childViewController, the UIPageViewController instance in our case.
[self.pageViewController didMoveToParentViewController:self];
// Assign the gestureRecognizers property of the pageViewController to the view's gestureRecognizers property
self.view.gestureRecognizers = self.pageViewController.gestureRecognizers;
Finally these are my delegate
methods (for example the method for the next VC)
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController
viewControllerAfterViewController:(UIViewController *)viewController
{
NSUInteger currentIndex = [self.modelArray indexOfObject:viewController];
if(currentIndex == self.modelArray.count - 1)
return nil;
UIViewController *cVC = [self.modelArray objectAtIndex:currentIndex + 1];
return cVC;
}
But when i build and run i get the following error.
Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 2147483648 beyond bounds [0 .. 3]'
Anybody can help me with this?
Kind regards.. EDIT
thread #1: tid = 0x2403, 0x37776350 libsystem_kernel.dylib`__pthread_kill + 8, stop reason = signal SIGABRT
frame #0: 0x37776350 libsystem_kernel.dylib`__pthread_kill + 8
frame #1: 0x33115122 libsystem_c.dylib`pthread_kill + 58
frame #2: 0x33151972 libsystem_c.dylib`abort + 94
frame #3: 0x36f2fd4e libc++abi.dylib`abort_message + 74
frame #4: 0x36f2cff8 libc++abi.dylib`default_terminate() + 24
frame #5: 0x3165ba76 libobjc.A.dylib`_objc_terminate() + 146
frame #6: 0x36f2d07a libc++abi.dylib`safe_handler_caller(void (*)()) + 78
frame #7: 0x36f2d114 libc++abi.dylib`std::terminate() + 20
frame #8: 0x36f2e598 libc++abi.dylib`__cxa_rethrow + 88
frame #9: 0x3165b9d0 libobjc.A.dylib`objc_exception_rethrow + 12
frame #10: 0x38c82f20 CoreFoundation`CFRunLoopRunSpecific + 456
frame #11: 0x38c82d48 CoreFoundation`CFRunLoopRunInMode + 104
frame #12: 0x34bbc2ea GraphicsServices`GSEventRunModal + 74
frame #13: 0x35c14300 UIKit`UIApplicationMain + 1120
frame #14: 0x0005050c Franke2`main(argc=1, argv=0x2fdb1d20) + 116 at main.m:16
frame #15: 0x340ccb20 libdyld.dylib`start + 4
Upvotes: 0
Views: 587
Reputation: 86
After calling the method indexOfObject:
you should verify that the returned index is not NSNotFound
witch is the returned value is the object is not in the array.
Your code should look more like this ;
NSUInteger currentIndex = [self.modelArray indexOfObject:viewController];
if(currentIndex == NSNotFound ||
currentIndex == self.modelArray.count - 1)
return nil;
In the future you should be able to find this bugs yourself by using the Xcode exception breakpoint.
Upvotes: 0
Reputation: 66224
2147483648 is NSNotFound, which is what -[NSArray indexOfObject:]
returns if the object is not found.
So in your line
NSUInteger currentIndex = [self.modelArray indexOfObject:viewController];
viewController
is not in modelArray
. This is because you are creating a new instance of the view controller each time.
On a side note, you are doing self.modelArray = [[NSMutableArray alloc] init];
and then doing nothing with that array, and throwing it away when you self.modelArray = pageData;
. No need to create two empty arrays there when you're just using one.
Upvotes: 2
Reputation: 4805
ViewOneViewController *cVC = [self.storyboard instantiateViewControllerWithIdentifier:@"ViewOne"];
NSArray *viewControllers = [NSArray arrayWithObject:cVC];
[self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
Here you are creating new object of ViewOneViewController and adding to viewControllers array of pageViewController. This cVC object has nothing to do with one you have added in modelArray before. These both are different objects of same class i.e. ViewOneViewController.
Hence you have to pass same objects from modelArray to viewControllers array of pageViewController so that you will not get garbage value when you do
NSUInteger currentIndex = [self.modelArray indexOfObject:viewController]; //will return garbage value in your case
From discussion of instantiateViewControllerWithIdentifier:
This method creates a new instance of the specified view controller each time you call it.
Upvotes: 0