Johannes Johannes - 3 months ago 63
iOS Question

Changing UIPageViewController's page programmatically doesn't update the UIPageControl

In my custom

UIPageViewController
class:

- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
self.model = [[BSTCMWelcomingPageViewModel alloc] init];
self.dataSource = self.model;
self.delegate = self;

self.pageControl = [UIPageControl appearance];
self.pageControl.pageIndicatorTintColor = [UIColor lightGrayColor];
self.pageControl.currentPageIndicatorTintColor = [UIColor blackColor];
}
return self;
}


Then I programmatically set the current
ViewController
when a button is hit:

- (void)scrollToNext
{
UIViewController *current = self.viewControllers[0];
NSInteger currentIndex = [self.model indexForViewController:current];
UIViewController *nextController = [self.model viewControllerForIndex:++currentIndex];
if (nextController) {
NSArray *viewControllers = @[nextController];
// This changes the View Controller, but PageControl doesn't update
[self setViewControllers:viewControllers
direction:UIPageViewControllerNavigationDirectionForward
animated:YES
completion:nil];
//Nothing happens!
[self.pageControl setCurrentPage:currentIndex];

//Error: _installAppearanceSwizzlesForSetter: Not a setter!
[self.pageControl updateCurrentPageDisplay];
}
}


If I can't do this with the
UIPageControl
that "belongs" to my
UIPageViewController
I will just try to make my own. But it would be nice if this was possible tho!

Answer

to update your UIPageControl indicator, you need to implement one data source method of UIPageViewController (the UIPageViewControllerDataSource method) :

-(NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController

This method is responsible for updating the page control indicator (when you use UIPageViewController). You only need to return the currentpage value in this method. The Method gets called by default when you use/make a call for setViewControllers on your custom UIPageViewController.

So the chunk of code that you need to write is:

- (void)scrollToNext
{
    UIViewController *current = self.viewControllers[0];
    NSInteger currentIndex = [self.model indexForViewController:current];
    UIViewController *nextController = [self.model viewControllerForIndex:++currentIndex];
    if (nextController) {
        NSArray *viewControllers = @[nextController];
       // This changes the View Controller and calls the presentationIndexForPageViewController datasource method
       [self setViewControllers:viewControllers
                   direction:UIPageViewControllerNavigationDirectionForward
                    animated:YES
                  completion:nil];
}

- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController
{
    return currentIndex;
}

Hope this solves your problem. :)