jueves, 14 de abril de 2016

iOS: UIPageViewController with input validation

1) Create a base view controller for the view controllers to be displayed in the page view controller
@interface PageContentViewController : UIViewController


@property(nonatomic, assign) NSUInteger pageIndex;
@property(nonatomic, retain) User* user;

- (BOOL)canGoToNext:(NSError**)error;

@end

@implementation PageContentViewController

...

- (BOOL)canGoToNext:(NSError**)error
{
    return YES; // Override in subclasses
}
2) Create a view controller to hold the page view controller
@interface CreateAccountViewController : UIViewController <UIPageViewControllerDataSource, UIPageViewControllerDelegate>

@property (strong, nonatomic) UIPageViewController *pageViewController;

@property (weak, nonatomic) IBOutlet UIPageControl *pageControl;

@end

@implementation CreateAccountViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.pageControl.numberOfPages = number_of_pages;

    // Create page view controller

    self.pageViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"PageViewController"];
    self.pageViewController.dataSource = self;
    self.pageViewController.delegate = self;

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

    CGSize containerSize = self.pageViewControllerContainer.frame.size;
    self.pageViewController.view.frame = CGRectMake(0, 0, containerSize.width, containerSize.height);

    [self addChildViewController:_pageViewController];

    [self.pageViewControllerContainer addSubview:_pageViewController.view];
    [self.pageViewControllerContainer bringSubviewToFront:self.pageControl];

    [self.pageViewController didMoveToParentViewController:self];

}

#pragma mark - UIPageViewControllerDataSource

- (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*)_viewControllerAtIndex:(NSUInteger)index
{
    NSArray* viewControllers = self.pageViewController.viewControllers;

    NSError* error;

    if (viewControllers && viewControllers.count > 0 && ![viewControllers[0] canGoToNext:&error]) {

        if (error) {
            [self showErrorDialogWithMessage:[error localizedDescription]];
            return nil;
        }
    }

    return [self viewControllerAtIndex:index];
}

- (UIViewController *)viewControllerAtIndex:(NSUInteger)index
{
    if (index >= number_of_pages) {
        return nil;
    }   

    switch (index) {
        // return appropriate view controller
    }
}

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

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

    index++;   

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

    return [self viewControllerAtIndex:index];
}

#pragma mark - UIPageViewControllerDelegate

- (void)pageViewController:(UIPageViewController *)pageViewController willTransitionToViewControllers:(NSArray<UIViewController *> *)pendingViewControllers NS_AVAILABLE_IOS(6_0)
{
    PageContentViewController* vc = (PageContentViewController*)pendingViewControllers[0];

    self.pageControl.currentPage = [vc pageIndex];
}

- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray<UIViewController *> *)previousViewControllers transitionCompleted:(BOOL)completed
{
    self.pageViewController.view.userInteractionEnabled = NO;  

    NSError* error;   

    if (![((PageContentViewController*)previousViewControllers[0]) canGoToNext:&error]) {
        [self performSelector:@selector(_goToPrevious:) withObject:error afterDelay:1];    

    } else {
        self.pageViewController.view.userInteractionEnabled = YES;
    }
}

- (void)_goToPrevious:(NSError*)error
{
    [self showErrorDialogWithMessage:[error localizedDescription]];

    [self previousPage:nil];
}

#pragma mark - IBActions

- (IBAction)nextPage:(id)sender
{
    NSInteger index = self.pageControl.currentPage;

    PageContentViewController* currentVC = (PageContentViewController*)[self viewControllerAtIndex:index];   

    NSError* error;

    if (index == 3 || ![currentVC canGoToNext:&error]) {       

        if (error) {
            [self showErrorDialogWithMessage:[error localizedDescription]];
        }       

        return;

    }
    PageContentViewController* nextVC = (PageContentViewController*)[self viewControllerAtIndex:index+1];

    self.pageControl.currentPage = index+1;  

    [self.pageViewController setViewControllers:@[nextVC] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil];

}

- (IBAction)previousPage:(id)sender
{
    NSInteger index = self.pageControl.currentPage;    

    if (index == 0) {
        return;
    }   

    PageContentViewController* previousVC = (PageContentViewController*)[self viewControllerAtIndex:index-1];   

    self.pageControl.currentPage = index-1;   

    __block CreateAccountViewController *blocksafeSelf = self;    

    dispatch_async(dispatch_get_main_queue(), ^{

        [self.pageViewController setViewControllers:@[previousVC] direction:UIPageViewControllerNavigationDirectionReverse animated:YES completion:^(BOOL finished){

            blocksafeSelf.pageViewController.view.userInteractionEnabled = YES;
        }];
    });
}

@end

No hay comentarios:

Publicar un comentario