I have a UIPageViewController
that uses an integer to tell which page it is on. It works fine, but if the user quickly swipes several times to get to a page further back, the integer changes more quickly than the views do, and then the whole thing falls apart (the app thinks it is on page 7 when it could be displaying page 3). What am I doing wrong? Is there a different method I should use to tell where I am? Thanks.
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController {
if (pageNumber == 0) {
pageNumber++;
NSLog(@"%i", pageNumber);
Two *two = [[Two alloc] init];
return two;
} else if (pageNumber == 1) {
pageNumber++;
NSLog(@"%i", pageNumber);
Three *three = [[Three alloc] init];
return three;
} else if (pageNumber >= 2) {
return nil;
} else {
return nil;
}
}
The problem is that you're taking pageNumber
for granted. UIPageViewController
could only be asking for next viewController
to preload it and you're already increasing pageNumber
.
You were close when you noticed that "this also happens if a user grabs the edge of the page and starts to move it, but then puts it and back stays on the current page."
This method gets UIViewController
for parameter and that is the only real reference you have.
Since you only have three pages one way to solve this would be:
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
if ([viewController isKindOfClass: [One class]])
{
Two *two = [[Two alloc] init];
return two;
}
else if ([viewController isKindOfClass: [Two class]])
{
Three *three = [[Three alloc] init];
return three;
}
else
{
return nil;
}
}
Note: this code is not the best solution - i'm just trying to point out that you shouldn't be simply increasing/decreasing pageNumber
in viewControllerAfterViewController:
/viewControllerBeforeViewController:
You could also [[... alloc ]init]
viewControllers before all this and reduce initialization activity of viewControllers in UIPageViewControllerDataSource
methods to loadView
(if it's not loaded) at most. For example (abbreviated):
...
if ([viewController isKindOfClass: [One class]])
{
//Two *two = [[Two alloc] init]; //called before and two is someone's property
if (![two isViewLoaded]) [two loadView];
return two;
}
else if ...
For more pages you could also try tagging viewControllers (during their initialization). Since UIViewController
itself doesn't have a tag property you could probably use viewController.view.tag
or sublcass UIViewController
and add it a pageNumber
property (this would probably be close to THE solution.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With