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

Ios UIPageViewController;如何处理动态变化的数据源,ios,uipageviewcontroller,Ios,Uipageviewcontroller,我正在创建一个动态的“wizard isch”分步功能,它基本上会引导用户通过一组视图,包括带有说明和信息的静态视图,以及在允许用户进入“下一个”视图之前需要用户干预(填写文本字段、与后端通信等)的动态视图 因此,我认为UIPageViewController是一个不错的方法,最初只将一个启动视图控制器设置为“欢迎” 然后使用UIPageViewControllerDataSource动态获取下一个视图。这样,我可以防止用户“走得太远”,而不必先在一个视图上填写所需信息,然后再允许用户滚动到下一

我正在创建一个动态的“wizard isch”分步功能,它基本上会引导用户通过一组视图,包括带有说明和信息的静态视图,以及在允许用户进入“下一个”视图之前需要用户干预(填写文本字段、与后端通信等)的动态视图

因此,我认为UIPageViewController是一个不错的方法,最初只将一个启动视图控制器设置为“欢迎”

然后使用
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始终询问数据源是否有可用的视图,无论是在当前视图之前还是之后

我仔细研究了一下,找到了一种我认为可行的方法,重新分配数据源,强制执行“缓存重置”

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

我希望能够找到一个合适的地方来重置数据源,在那里我知道没有正在进行的动画。但是,只有当有要滚动到的视图时,才会调用委托
pageViewController:didFinishAnimating:PreviousViewController:transitionCompleted:
。在我的例子中,如果用户处于当前的“最后一个”视图,视图将被“拖动”,但没有新视图可用

或者,另一种解决方案是在第一个/最后一个视图中禁用UIPageViewController的“拖动”动画。。。我不知道——陷入困境,需要第二种意见;)有什么想法/建议吗

最好的,
/Markus

如果要从
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

如果我理解正确,调用
setViewControllers:direction:animated:completion:
强制缓存重置?这个
Additions
category添加了一个实用功能来基本上设置/重置当前可见的视图?我不太明白neighborViewController的内容,因为我只想使用当前视图,清除缓存时不是下一个/上一个方法?使用category中的该方法,您可以设置
UIViewController
,如果需要强制重置
UIPageViewController
中的缓存数据,请基于参数值
invalidateCache
。我只是不喜欢使用我不理解其目的的代码段……;)因此,我的问题是为什么要重置
UIPageViewController
的缓存-
setViewControllers:…
会隐式导致控制器重置缓存,或者?如果是这样的话,为什么要使用邻居视图而不是当前的
作为参考呢?我正在阅读有关
UIPageViewController
缓存的文章,通常它是有线工作的。如果您将从代码中设置当前的
UIViewController
,即您有4个viewcontroller,并从第一个设置“转到第三个viewcontroller”,则
UIPageViewController
将渲染新VC,但当您尝试转到第二个
UIViewController
(通过滑动手势)时,则将渲染第一个,即使您正确地设置了数据源,另外,也不会从数据源调用beforeViewController方法。要总结,您必须将所有3个
UIViewControllers
设置为清除缓存。
@interface UIPageViewController (Additions)

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

@end
@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