UIPageViewController在iOS中自动滚动

时间:2014-10-31 06:14:38

标签: ios objective-c uipageviewcontroller

我正在创建一个应用程序,其中PageViewController应该在某个时间间隔内滚动。目前我一直做到手动滚动。用户可以滚动任何图像,它将工作。但坚持用用户触摸实现自动滚动。以下是我的代码。请帮帮我。

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    _pageTitles = @[@"", @"", @"", @""];
    _pageImages = @[@"page1.png", @"page2.png", @"page3.png", @"page4.png"];

    // Create page view controller
    self.pageViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"PageViewController"];
    self.pageViewController.dataSource = self;

    PageContentViewController *startingViewController = [self viewControllerAtIndex:0];
    NSArray *viewControllers = @[startingViewController];
    [self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];

    // Change the size of page view controller
    self.pageViewController.view.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height - 50);

    [self addChildViewController:_pageViewController];
    [self.view addSubview:_pageViewController.view];
    [self.pageViewController didMoveToParentViewController:self];
}

- (PageContentViewController *)viewControllerAtIndex:(NSUInteger)index
{
    if (([self.pageTitles count] == 0) || (index >= [self.pageTitles count])) {
        return nil;
    }

    // Create a new view controller and pass suitable data.
    PageContentViewController *pageContentViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"PageContentViewController"];
    pageContentViewController.imageFile = self.pageImages[index];
    pageContentViewController.titleText = self.pageTitles[index];
    pageContentViewController.pageIndex = index;

    return pageContentViewController;
}

-(void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:YES];

    self.navigationController.navigationBar.hidden = YES;
}

#pragma mark - Page View Controller Data Source

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
    NSUInteger index = ((PageContentViewController*) viewController).pageIndex;

    if ((index == 0) || (index == NSNotFound)) {
        return nil;
    }

    index--;
    return [self viewControllerAtIndex:index];
}

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
    NSUInteger index = ((PageContentViewController*) viewController).pageIndex;

    if (index == NSNotFound) {
        return nil;
    }

    index++;
    if (index == [self.pageTitles count]) {
        return nil;
    }
    return [self viewControllerAtIndex:index];
}

- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController
{
    return [self.pageTitles count];
}

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

3 个答案:

答案 0 :(得分:3)

@Daniel您的链接已损坏,您的回答是"几乎没有解释你的问题的解决方案。对于那些有兴趣阅读UIPageViewController Class文档的人。

这里要注意的方法是:

- (void)setViewControllers:(NSArray *)viewControllers
                 direction:(UIPageViewControllerNavigationDirection)direction
                  animated:(BOOL)animated
                completion:(void (^)(BOOL finished))completion

UIPageViewController希望您根据值告诉它要传递什么数据以及使用什么控制器。在这里,我告诉我的UIPageController子类是委托和dataSouce。配置委托方法和viewControllerAtIndex dataSource方法后,我添加了一个调用我的loadNextController方法的自定义间隔。在那种方法中,我正在检查" next"控制器是零。如果它不是零,我通过" next"控制器作为@ [启动控制器]回到第二次调用setViewControllers。如果它为零,我只需将索引值重置为ZERO并使用我的" next"调用setViewControllers。控制器作为@ [启动控制器]。此自定义子类用于自动寻呼到下一个或第一个控制器。奖励是用户交互仍然由UIPageViewController类处理。

注意:初始调用setViewControllers是必需的,因为你的UIPageViewContrller不知道如果可以先加载任何viewController。我对setViewControllers的第二次调用只是跳到下一个或第一个viewController。

- (void)viewDidLoad {
    [super viewDidLoad];
    self.index = 0;
    self.delegate = self;
    self.dataSource = self;

    /*! setup an interval */
    [NSTimer scheduledTimerWithTimeInterval:10.0
                                     target:self
                                   selector:@selector(loadNextController)
                                   userInfo:nil
                                    repeats:YES];

    /*! set starting controller */
    NSArray *startingViewControllers = @[[self  viewControllerAtIndex:self.index]];

    [self setViewControllers: startingViewControllers
                   direction: UIPageViewControllerNavigationDirectionForward
                    animated: YES
                  completion: nil];
}

- (UIViewController*)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController {
    NSUInteger index = ((YSPageContentViewController*) viewController).pageIndex;
    if (index > 0 ) {
        return [self viewControllerAtIndex:index-1];
    }
    return nil;
}

- (UIViewController*)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController {
    NSUInteger index = ((YSPageContentViewController*) viewController).pageIndex;
    if (index+1 < [self.items count] ) {
        return [self viewControllerAtIndex:index+1];
    }
    return nil;
}

- (PageContentViewController *)viewControllerAtIndex:(NSUInteger)index{
    if (index < [self.items count]) {
        PageContentViewController *pageContentViewController =   [[PageContentViewController alloc]init];
        pageContentViewController.pageIndex = index;
        pageContentViewController.image = (UIImage*)self.items[index];
        return pageContentViewController;
    }
    return nil;
}

/*! set next controller */
- (void)loadNextController {
    PageContentViewController *nextViewController = [self viewControllerAtIndex:self.index++];
    if (nextViewController == nil) {
        self.index = 0;
        nextViewController = [self viewControllerAtIndex:self.index];
    }
    [self setViewControllers:@[nextViewController]
                   direction:UIPageViewControllerNavigationDirectionForward
                    animated:YES
                  completion:nil];
} 

注意:这确实有效;但是当内部手势识别器更改控制器时,我并不总是返回正确的控制器。在某个地方,我正在失去对索引的追踪。我将用完成的实现来更新它。

答案 1 :(得分:1)

研究@Ryan的回答。修复了@Ryan问题&#34;但是当内部手势识别器更改控制器时,我并不总是返回正确的控制器。在某个地方,我正在失去对指数的追踪。&#34;

刚编辑了几行,它对我有用。想分享一些人需要的东西。

- (void)viewDidLoad
{
[super viewDidLoad];
_pageTitles = @[@"Tips n Tricks", @"Join to learn", @"Share to get points"];
self.pageViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"PageViewController"];
self.pageViewController.dataSource = self;
self.pageViewController.delegate = self;

[NSTimer scheduledTimerWithTimeInterval:10.0
                                 target:self
                               selector:@selector(loadNextController)
                               userInfo:nil
                                repeats:YES];
PageContentViewController *startingViewController = [self viewControllerAtIndex:0];
NSArray *viewControllers = @[startingViewController];
[self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];

// Change the size of page view controller

self.pageViewController.view.frame = _containerView.frame;
self.pageControl.numberOfPages = _pageTitles.count;
self.pageControl.currentPage = 0;
[self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil];
[self addChildViewController:_pageViewController];
[self.view addSubview:_pageViewController.view];
[self.pageViewController didMoveToParentViewController:self];
[self.view bringSubviewToFront:self.pageControl];

}

实现了PageViewController的数据源方法

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
    NSUInteger index = ((PageContentViewController*) viewController).pageIndex;
    if ((index == 0) || (index == NSNotFound)) {
        index = _pageTitles.count;
    }
    index--;
    return [self viewControllerAtIndex:index];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
    NSUInteger index = ((PageContentViewController*) viewController).pageIndex;
        if (index == NSNotFound) {
            return nil;
    }
    index++;
    if (index == [self.pageTitles count]) {
        index = 0;
    }
    return [self viewControllerAtIndex:index];
}
- (PageContentViewController *)viewControllerAtIndex:(NSUInteger)index
{
    if (([self.pageTitles count] == 0) || (index >= [self.pageTitles count])) {
        return nil;
    }
    PageContentViewController *pageContentViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"PageContentViewController"];
    pageContentViewController.titleText = self.pageTitles[index];
    pageContentViewController.pageIndex = index;
    return pageContentViewController;
}

实现了PageController委托的didFinishAnimating方法,以获取PageViewController的当前索引并相应地更新PageControl

- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed
{
    PageContentViewController *currentViewController = pageViewController.viewControllers[0];
    currentIndex = (int)currentViewController.pageIndex;
    [self.pageControl setCurrentPage:currentIndex];
}

以及最后实现的方法来更新动画上的PageViewController

- (void)loadNextController {
    currentIndex++;
    PageContentViewController *nextViewController = [self viewControllerAtIndex:currentIndex];
    if (nextViewController == nil) {
        currentIndex = 0;
        nextViewController = [self viewControllerAtIndex:currentIndex];
    }
    [self.pageViewController setViewControllers:@[nextViewController] direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
    [self.pageControl setCurrentPage:currentIndex];
}

当前索引是全局声明的,用于跟踪当前的PageViewController索引并相应地更新PageController。

希望它有所帮助..快乐编码.. :)

答案 2 :(得分:0)

您正在寻找的方法可能是setViewControllers:direction:animated:completion:

当然,您需要提供想要在动画结束时可见的视图控制器。

您可以使用动画设置调用此设置为YES,控制器将自动翻页:)

请参阅documentation了解更多