I am making one app, in which PageViewController should scroll in some time interval. Currently I have done till manual scrolling. User can scroll any images and it will wor
Perhaps the method you are looking for is setViewControllers:direction:animated:completion:
Naturally you will need to supply the view controllers you want to be visible at the end of the animation.
You can call this with animated set to YES and the controller will page automatically:)
See the documentation for more
Worked on @Ryan's answer. Fixed @Ryan issue "however I am not always returning the correct controller when the internal gesture recognizer changes the controller. Somewhere along the way I am losing track of the index."
Just edited few lines and it worked for me. Thought to share in case some one needs the same.
- (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];
}
Implemented datasource methods of 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;
}
Implemented didFinishAnimating method of PageController delegate to get to get current index of PageViewController and update PageControl accordingly
- (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];
}
and in last implemented method to update PageViewController on animation
- (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];
}
Current index is declared globally to keep track of current PageViewController's index and update PageController accordingly.
Hope it helps.. Happy Coding.. :)
@Daniel your link is broken and your "answer" does little to explain your solution to the question. For those interested in reading documentation for the UIPageViewController Class.
The method to pay attention to here is :
- (void)setViewControllers:(NSArray *)viewControllers
direction:(UIPageViewControllerNavigationDirection)direction
animated:(BOOL)animated
completion:(void (^)(BOOL finished))completion
The UIPageViewController expects you to tell it what data to deliver and what controller to use based on a value. Here I am telling my UIPageController Subclass to be the delegate and dataSouce. After configuring the delegate methods and the viewControllerAtIndex dataSource method, I added a custom interval which calls my loadNextController method. In that method I am checking to see if the "next" controller is nil. If it is not nil I pass the "next" controller as the @[starting controller] back to a second call to setViewControllers. If it is nil I just reset the index value to ZERO and call setViewControllers with my "next" controller as the @[starting controller]. This custom subclass serves to page to the next or first controller automatically. The bonus is that user interaction is still handled by the UIPageViewController Class.
Note: The initial call to setViewControllers is required because your UIPageViewContrller will not know what if any viewController can be loaded first. My second call to setViewControllers does nothing more than skip to the next or first 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];
}
Note: This does work; however I am not always returning the correct controller when the internal gesture recognizer changes the controller. Somewhere along the way I am losing track of the index. I will update this with my finished implementation.