UIPageViewController中的断言失败

时间:2014-09-09 08:46:53

标签: ios xcode uipageviewcontroller

在UIPageViewController中,在Tabs之间切换太快,App在行中崩溃

[UIPageViewController queuingScrollView:didEndManualScroll:toRevealView:direction:animated:didFinish:didComplete:]

有错误断言失败并因未捕获的异常'NSInternalInconsistencyException'而终止应用程序,原因:'没有视图控制器管理可见视图。

错误记录如下

*** Assertion failure in -[UIPageViewController queuingScrollView:didEndManualScroll:toRevealView:direction:animated:didFinish:didComplete:], /SourceCache/UIKit/UIKit-3318.0.1/UIPageViewController.m:1875
2014-09-29 11:34:00.770 Wowcher[193:9460] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'No view controller managing visible view <UIView: 0x1783fa80; frame = (0 0; 320 416); autoresize = W+RM+H+BM; layer = <CALayer: 0x17898540>>'
*** First throw call stack:
(0x219fbf87 0x2f15ac77 0x219fbe5d 0x226cb2c9 0x253f9fff 0x2546f8d3 0x2546f6b7 0x2546c2b9 0x254700db 0x25470f97 0x2546d037 0x24ea925f 0x2500a589 0x24ff7eef 0x24ea677d 0x252b8c81 0x24e70105 0x24e6e07f 0x24ea4b6d 0x24ea443d 0x24e7acc5 0x250ee513 0x24e79707 0x219c2807 0x219c1c1b 0x219c0299 0x2190ddb1 0x2190dbc3 0x28c99051 0x24ed9a31 0xd950b 0xca6e0)
libc++abi.dylib: terminating with uncaught exception of type NSException

提前致谢

6 个答案:

答案 0 :(得分:24)

所以我对此的解决方案是添加BOOL来跟踪我的动画状态。因此,在设置新的ViewController之前,我也会修改它:

if (!_transitionInProgress) {
    _transitionInProgress = YES;
    [self.pageController setViewControllers:@[viewController] direction:UIPageViewControllerNavigationDirectionReverse animated:YES completion:^(BOOL finished) {
        _transitionInProgress = !finished;
    }];
}

所以我在设置新的视图控制器之前等待我的动画完成。在我的情况下,我有一些按钮,用户可以按下以切换页面。这也可以防止它们通过它们过快,因此动画总是流畅而且很好

答案 1 :(得分:10)

这是UIPageViewController在滚动模式下的内部实现中的一个错误。当页面视图控制器已经为转换设置动画时发生转换动画时会发生这种情况。我最终做的是阻止UI允许多个快速滚动。我有两个按钮,左右两个,使页面视图控制器滚动到上一页或下一页控制器。我会在动画播放时禁用按钮的操作。页面视图控制器的委托告诉您在所有动画停止后,您需要知道何时禁用UI的功能以及何时重新启用它。

答案 2 :(得分:3)

我也遇到了这个问题,但问题是我无法始终如一地重现问题,但我可以从崩溃日志中看到问题存在。

我有一个pageviewcontroller,它允许用户滑动,并且视图也可以通过编程方式滚动。当你刚刚进入屏幕时,应用程序有时会崩溃,但在接下来的尝试中它可以正常工作,所以它有点疯狂。即使我提出修复,我也无法确定它是否有效,因为我无法重现它。看起来下面的代码应该修复它(从Removing a view controller from UIPageViewController获取)至少屏幕表现得更好用这个代码。我真的很感激,如果我自己能够获得一些方法来注入这个崩溃,那么我可以验证修复。

- (void) setViewControllers:(NSArray*)viewControllers direction:(UIPageViewControllerNavigationDirection)direction animated:(BOOL)animated completion:(void (^)(BOOL))completion {

    if (!animated) {
        [super setViewControllers:viewControllers direction:direction animated:NO completion:completion];
        return;
    }

    [super setViewControllers:viewControllers direction:direction animated:YES completion:^(BOOL finished){

        if (finished) {
            dispatch_async(dispatch_get_main_queue(), ^{
                [super setViewControllers:viewControllers direction:direction animated:NO completion:completion];
            });
        } else {
            if (completion != NULL) {
                completion(finished);
            }
        }
    }];
}

答案 3 :(得分:1)

这里有一个非常好的讨论:

Removing a view controller from UIPageViewController

接受的答案讨论了这个问题:

&#34;我不知道为什么会发生这种情况,我回溯并最终开始使用Jai的答案作为解决方案,创建一个全新的UIPageViewController,将其推送到UINavigationController然后弹出旧的。毛,但它的确有效 - 主要是。我一直在发现我仍然偶尔会从UIPageViewController获得断言失败,如下所示:

  
      
  • 断言失败 - [UIPageViewController queuingScrollView:didEndManualScroll:toRevealView:direction:animated:didFinish:didComplete:],   /SourceCache/UIKit_Sim/UIKit-2380.17/UIPageViewController.m:1820 $ 1 =   154507824没有视图控制器管理可见视图&gt;
  •   

应用程序崩溃了。为什么?好吧,搜索,我发现了我提到的另一个问题,特别是提出我最初想法的接受的答案,只需调用setViewControllers: animated:YES,然后一旦完成调用setViewControllers: animated:NO查看控制器以重置UIPageViewController,但它有缺少的元素:在主队列上调用该代码!这是代码:&#34;

答案 4 :(得分:0)

我通过在edgesForExtendedLayout = UIRectEdgeNone子类上设置UIPageViewController修复了问题:

- (instancetype)initWithTransitionStyle:(UIPageViewControllerTransitionStyle)style navigationOrientation:(UIPageViewControllerNavigationOrientation)navigationOrientation options:(NSDictionary<NSString *,id> *)options
{
    self = [super initWithTransitionStyle:style navigationOrientation:navigationOrientation options:options];

    self.edgesForExtendedLayout = UIRectEdgeNone;

    return self;
}

答案 5 :(得分:0)

我也遇到了同样的情况,我的应用程序同时具有滑动和下一个及上一个按钮来回导航。 要解决该问题,请在初始化时将其本地Bool变量设置为true(例如,私有var canScroll :Bool = true ),然后在导航的第一行中检查条件使用Guard的方法,然后将Bool值设置为 false setViewcontroller 方法。在动画完成时,将相同的布尔值设置为 true ,以便在视图控制器过渡时执行滑动动作时,guard语句会检查 canScroll 是否为true它返回。这样可以避免分页时出现崩溃问题,这是我下一步的代码。

 @IBAction func nextAction(_ sender: Any) {
            guard canScroll == true else { return } //check condition
            guard featureCount > 0 else { return }
    guard let index = self.viewControllerAtIndex(indexRow) else { return }
            let startingViewController: OnBoardModelViewController = index
            canScroll = false 
            pageViewController?.setViewControllers([startingViewController],
                                                   direction: UIPageViewControllerNavigationDirection.forward,
                                                   animated: true,
                                                   completion: {_ in
                                                    self.canScroll = true
            })
}