UIPageViewController;如何处理动态变化的数据源

时间:2014-04-15 13:27:21

标签: ios uipageviewcontroller

我正在创建一个动态的“向导式”逐步功能,它基本上将引导用户完成一系列视图,包括带有指令和信息的静态视图,以及需要用户干扰的动态视图(填写完成)在允许用户进入“下一个”视图之前,文本字段,后端通信等...)。

因此,我认为UIPageViewController是一个很好的方法,最初只设置一个启动视图控制器来说“欢迎”;

[self setViewControllers:@[welcomeViewController]
               direction:UIPageViewControllerNavigationDirectionForward
                animated:NO
              completion:nil];

然后,使用UIPageViewControllerDataSource动态获取下一个视图。这样,在允许用户滚动到下一个带有更多指令的视图等之前,我可以阻止用户前进“太远”,而不先在一个视图上填写所需信息......

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
    //Check if the user has filled out everything that needs to be done

    //If all is good, allow for the next view to appear
    if (...) 
        return nextViewController;
    else
        return nil;
}

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
    //Check if the user is allowed to go back to the previous view -- some views are not possible to go back to

    //If all is good, allow for the previous view to appear
    if (...) 
        return previousViewController;
    else
        return nil;
}

我已经构建了架构数据管理的东西,使它工作,一切都很好。但是,UIPageViewController缓存我的数据源答案,我说“不,没有上一个/下一个视图......”,这意味着当用户填写了需要完成的内容并被授予访问权限时,刷卡的次数并不重要;缓存说没有什么可以刷到的。

所以,我需要找到一种重置缓存的方法,强制UIPageViewController 始终询问数据源是否有任何可用的视图,都在当前之前。

我已经挖了一下,找到了一个我认为可行的好方法,通过重新分配强制执行“缓存重置”的数据源;

//Enforce a cache reset after 1 sec
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{

    //Reset/reassign data source, which will cause cached data-VCs to be thrown
    DDLogInfo(@"Resetting data source");
    self.dataSource = nil;
    self.dataSource = self;
});

但是,我找不到一个合适的位置来执行它,因为当数据源被重置/重新分配时,由于手势/滑动而导致的任何正在进行的动画也将被重置,这导致UI不良。

我希望能够找到一个合适的位置来重置数据源,我知道没有正在进行的动画。但只有在有滚动视图的情况下才会调用委托pageViewController:didFinishAnimating:previousViewControllers:transitionCompleted:。并且,在我的情况下,如果用户处于当前“最后”视图,则视图将被“拖动”但没有新视图可用。

或者,一个不同的解决方案是禁用UIPageViewController在第一个/最后一个视图中“拖动”动画...我不知道 - 卡住并需要第二意见;)任何想法/建议?

最佳, /马库斯

1 个答案:

答案 0 :(得分:0)

如果要从UIPageViewController重置缓存,请使用此类别

UIPageViewController+Additions.h

@interface UIPageViewController (Additions)

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

@end

UIPageViewController+Additions.m

@implementation UIPageViewController (Additions)
- (void)setViewControllers:(NSArray *)viewControllers direction:(UIPageViewControllerNavigationDirection)direction invalidateCache:(BOOL)invalidateCache animated:(BOOL)animated completion:(void (^)(BOOL finished))completion {
    NSArray *vcs = viewControllers;
    __weak UIPageViewController *mySelf = self;

    if (invalidateCache && self.transitionStyle == UIPageViewControllerTransitionStyleScroll) {
        UIViewController *neighborViewController = (direction == UIPageViewControllerNavigationDirectionForward
                                                    ? [self.dataSource pageViewController:self viewControllerBeforeViewController:viewControllers[0]]
                                                    : [self.dataSource pageViewController:self viewControllerAfterViewController:viewControllers[0]]);
        [self setViewControllers:@[neighborViewController] direction:direction animated:NO completion:^(BOOL finished) {
            [mySelf setViewControllers:vcs direction:direction animated:animated completion:completion];
        }];
    }
    else {
        [mySelf setViewControllers:vcs direction:direction animated:animated completion:completion];
    }
}
@end