奇怪的是,没有直接的方法可以做到这一点.考虑下面的情景:
- 您有一个带有1个页面的页面视图控制器.
- 添加另一页(共2页)并滚动至该页.
- What I want is,当用户滚动回第一页时,第二页现在被删除并取消分配,用户不能再刷回该页.
在转换完成后,我try 将视图控制器作为子视图控制器删除,但它仍然允许我滚动回空页面(它不会"调整"页面视图的大小)
我想做的事可能吗?
奇怪的是,没有直接的方法可以做到这一点.考虑下面的情景:
在转换完成后,我try 将视图控制器作为子视图控制器删除,但它仍然允许我滚动回空页面(它不会"调整"页面视图的大小)
我想做的事可能吗?
虽然这里的答案都是信息性的,但这里给出了另一种处理问题的方法:
UIPageViewController navigates to wrong page with Scroll transition style
当我第一次搜索这个问题的答案时,我搜索时的措辞让我陷入了这个问题,而不是我刚刚链接到的那个问题,所以我觉得有义务发布一个链接到另一个问题的答案,现在我已经找到了它,并且进行了一点详细阐述.
matt here很好地描述了这个问题:
这实际上是UIPageViewController中的一个错误.它仅在滚动样式(UIPageViewControllerTransitionStyleScroll)和
不要使用UIPageViewControllerTransitionStyleScroll.
或者,如果调用SetViewController:direction:animated:completion:,则使用
要清楚地看到错误,请致电
出现错误的原因似乎是,当使用滚动时
这是一个很好的描述,不完全是这个问题中提到的问题,但非常接近.请注意,如果使用animated:NO
执行setViewControllers
,用户下次用手势平移时,您将强制UIPageViewController重新查询其数据源,因为它不再"知道自己在哪里"或当前视图控制器旁边的视图控制器.
然而,这对我来说不起作用,因为有时我需要通过编程将页面视图在动画中移动with左右.
所以,我的第一个 idea 是用动画调用setViewControllers
,然后在完成块中,用现在显示的视图控制器调用该方法,但没有动画.所以用户可以平移,很好,但是我们再次调用该方法来重置页面视图.
不幸的是,当我try 这样做时,我开始从页面视图控制器中得到奇怪的"断言错误".它们看起来像这样:
***-[UIPageViewController queuingScrollView:]中的断言失败...
由于不知道发生这种情况的确切原因,我回过头来,最终开始使用Jai's answer作为解决方案,创建了一个全新的UIPageViewController,将其推到一个UINavigationController上,然后弹出旧的.虽然很恶心,但基本上是有效的.我发现UIPageViewController仍会偶尔出现断言失败,比如:
*** Assertion failure in -[UIPageViewController queuingScrollView:didEndManualScroll:toRevealView:direction:animated:didFinish:didComplete:], /SourceCache/UIKit_Sim/UIKit-2380.17/UIPageViewController.m:1820 $1 = 154507824 No view controller managing visible view >
应用程序崩溃了.为什么?在搜索过程中,我找到了上面提到的other question个,尤其是accepted answer,它支持我最初的 idea ,简单地调用setViewControllers: animated:YES
,然后用相同的视图控制器调用setViewControllers: animated:NO
,以重置UIPageViewController,但它缺少一个元素:在主队列上调用该代码!以下是代码:
__weak YourSelfClass *blocksafeSelf = self;
[self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:^(BOOL finished){
if(finished)
{
dispatch_async(dispatch_get_main_queue(), ^{
[blocksafeSelf.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:NULL];// bug fix for uipageview controller
});
}
}];
哇!这对我来说真正有意义的唯一原因是,我观看了WWDC 2012会话211,在iOS上构建并发用户界面(可通过开发帐户获得here).我现在回想起来,试图修改UIKit对象(如UIPageViewController)所依赖的数据源对象,并在辅助队列上进行修改,可能会导致一些严重的崩溃.
我从未见过有特别记录的,但现在必须假设是这样的,并且仔细阅读,动画的完成块是在辅助队列上执行的,而不是在主队列上执行的.所以UIPageViewController发出嘎嘎声并给出断言失败的原因,当我最初试图在setViewControllers animated:YES
的完成块中调用setViewControllers animated:NO
时,以及现在我只是使用UINavigationController来推送一个新的UIPageViewController(但在setViewControllers animated:YES
的完成块中再次这样做),都是因为这都发生在那个辅助队列上.
这就是为什么上面的代码可以完美地工作,因为您来自动画完成块,并将其发送回主队列,这样就不会与UIKit交叉流.明亮的
无论如何,我想分享这段旅程,以防有人遇到这个问题.
编辑:Swift版本here,如果有人感兴趣.