以编程方式更改UIPageViewController的页面不会更新UIPageControl

Joh*_*nes 16 iphone cocoa-touch ios

在我的自定义UIPageViewController类中:

- (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;
}
Run Code Online (Sandbox Code Playgroud)

然后我以编程方式设置ViewController按下按钮时的当前值:

- (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];
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我不能用UIPageControl"属于"我这样做,UIPageViewController我会尝试自己制作.但如果这是可能的话会很好!

ans*_*hul 27

要更新您的UIPageControl指标,您需要实现UIPageViewController的一个数据源方法(UIPageViewControllerDataSource方法):

-(NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController
Run Code Online (Sandbox Code Playgroud)

此方法负责更新页面控件指示符(当您使用UIPageViewController时).您只需要在此方法中返回当前页面值.当您在自定义UIPageViewController上使用/调用setViewControllers时,默认情况下会调用Method.

所以你需要编写的代码块是:

- (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;
}
Run Code Online (Sandbox Code Playgroud)

希望这能解决你的问题.:)

  • 这怎么样?currentIndex是一个实例var,如果是这样,你为什么要在scrollToNext中声明它? (2认同)

mic*_*c3r 7

如接受的答案所述,您需要实施

- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController
Run Code Online (Sandbox Code Playgroud)

但对我来说,使用它就足够了:

Objective-C的:

- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController {
    // The selected item reflected in the page indicator.
    return [self.controllers indexOfObject:[pageViewController.viewControllers firstObject]];
}
Run Code Online (Sandbox Code Playgroud)

Swift 3+:

func presentationIndex(for pageViewController: UIPageViewController) -> Int {
        guard let index = viewControllers?.index(of: (pageViewController.viewControllers?.first)!) else { return 0 }
        return index
}
Run Code Online (Sandbox Code Playgroud)

无需记住当前索引.当self.controllers被一个NSArrayUIViewControllers显示中给出UIPageViewController.我不确定你的BSTCMWelcomingPageViewModel作品究竟如何,但它应该很容易调整.