奇怪的是,没有直接的方法可以做到这一点.考虑下面的情景:

  1. 您有一个带有1个页面的页面视图控制器.
  2. 添加另一页(共2页)并滚动至该页.
  3. What I want is,当用户滚动回第一页时,第二页现在被删除并取消分配,用户不能再刷回该页.

在转换完成后,我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,如果有人感兴趣.

Objective-c相关问答推荐

在 iOS 7 上,如果最终包含在选项卡栏控制器中,则使用工具栏推送控制器会留下不可用空间的间隙

iphone keys 串项目在应用程序卸载后仍然存在?

如何删除警告按钮的框架在运行时会有所不同.

如何将 CGPoint 添加到 NSMutableArray?

如何获取 AppIcon 的 UIImage?

如何以编程方式暂停 NSTimer?

iOS框架改变一个属性(例如宽度)

以编程方式创建 UITableView

奇怪的错误 NSAssert

在Objective-C中替换字符串中的一个字符

alloc 和 allocWithZone: 有什么区别?

Xcode 在 iOS 8 中的 Main() 中引发异常,并带有所有异常断点

获取字符串的最后 2 个字符?

从 iPhone 设备查找当前国家

Objective-C 中的属性和实例变量

Objective-c 中 SEL 类型的属性

为什么 detailTextLabel 不可见?

使用 UINavigationController 在 UIPageViewController 中下推内容

最大 CGFloat 值是否有常数?

找出窗口中的 UIBarButtonItem 框架?