xcode UIPageViewController 中的断言失败
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25740245/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Assertion failure in UIPageViewController
提问by Brjv
While switching between Tabs too fast in UIPageViewController, App getting crash in line
在 UIPageViewController 中切换选项卡太快时,应用程序崩溃
[UIPageViewController queuingScrollView:didEndManualScroll:toRevealView:direction:animated:didFinish:didComplete:]
with errors Assertion failure and Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'No view controller managing visible view.
由于未捕获的异常“NSInternalInconsistencyException”,错误断言失败和终止应用程序,原因:“没有视图控制器管理可见视图。
Error Log as below
错误日志如下
*** 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
Thanks in advance
提前致谢
回答by Andrei Filip
So my solution to this was adding a BOOL
which keeps track of my animations state. So before setting the new ViewController
, I modify this too:
所以我的解决方案是添加一个BOOL
跟踪我的动画状态的。所以在设置 new 之前ViewController
,我也修改了这个:
if (!_transitionInProgress) {
_transitionInProgress = YES;
[self.pageController setViewControllers:@[viewController] direction:UIPageViewControllerNavigationDirectionReverse animated:YES completion:^(BOOL finished) {
_transitionInProgress = !finished;
}];
}
So I'll wait for my animation to finish before setting a new view controller. In my case, I have a some buttons the user can press in order to switch pages. This also prevents them from going too fast through them so the animations are always smooth and nice
所以我会在设置新的视图控制器之前等待我的动画完成。就我而言,我有一些按钮,用户可以按下以切换页面。这也可以防止它们通过它们过快,因此动画始终流畅美观
回答by Leo Natan
This is a bug in the internal implementation of UIPageViewController in scroll mode. It happens when a transition animation occurs while the page view controller is already animating a transition. What I ended up doing was to block the UI from allowing multiple quick scrolls. I have two buttons, left and right, which make the page view controller scroll to previous or next page controller. I disable the buttons' operation while there is an animation going. The page view controller's delegate tells you all you need to know when to disable the UI's functionality and when to re-enable it, once all animations have stopped.
这是滚动模式下 UIPageViewController 内部实现的一个 bug。当页面视图控制器已经在动画过渡时发生过渡动画时会发生这种情况。我最终做的是阻止 UI 允许多次快速滚动。我有两个按钮,向左和向右,它们使页面视图控制器滚动到上一页或下一页控制器。我在播放动画时禁用按钮操作。页面视图控制器的委托会告诉您所有需要知道的信息,一旦所有动画都停止,何时禁用 UI 的功能以及何时重新启用它。
回答by anoop4real
I am also facing this problem, but the issue is that I am unable to consistently reproduce the problem, but I can see from the crashlogs that the issue exists.
我也面临这个问题,但问题是我无法始终如一地重现该问题,但我可以从崩溃日志中看到该问题存在。
I have the pageviewcontroller which allows the user to swipe and also the view scrolls programmatically. The app crashes sometimes when you just enter the screen, but in the next attempts it works fine, so its kind of crazy. Even if I put a fix I cant be sure that it works as I am unable to reproduce it. Looks like the below code should fix it (took from Removing a view controller from UIPageViewController) atleast the screen behaves better with this code. I would really appreciate if I can get some methods to inject this crash myself, so that I can verify the fix.
我有 pageviewcontroller,它允许用户滑动并且视图以编程方式滚动。当你刚进入屏幕时,应用程序有时会崩溃,但在接下来的尝试中它运行良好,所以它有点疯狂。即使我进行了修复,我也无法确定它是否有效,因为我无法重现它。看起来下面的代码应该修复它(取自从 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);
}
}
}];
}
回答by Steve Rosenberg
There is a really good discussion here:
这里有一个非常好的讨论:
Removing a view controller from UIPageViewController
从 UIPageViewController 中删除视图控制器
The accepted answer discusses this:
接受的答案讨论了这一点:
"Not knowing exactly why this was happening, I backtracked and eventually started using Jai's answer as a solution, creating an entirely new UIPageViewController
, pushing it onto a UINavigationController
, then popping out the old one. Gross, but it works--mostly. I have been finding I'm still getting occasional Assertion Failures from the UIPageViewController
, like this one:
“不知道为什么会发生这种情况,我回溯并最终开始使用 Jai 的答案作为解决方案,创建一个全新的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 >
- 断言失败 -[UIPageViewController queuingScrollView:didEndManualScroll:toRevealView:direction:animated:didFinish:didComplete:], /SourceCache/UIKit_Sim/UIKit-2380.17/UIPageViewController.m:1820 $1 = 154507824 视图控制器管理可见视图 > 无
And the app crashes. Why? Well, searching, I found this other question that I mentioned up top, and particularly the accepted answer which advocates my original idea, of simply calling setViewControllers: animated:YES
and then as soon as it completes calling setViewControllers: animated:NO
with the same view controllers to reset the UIPageViewController
, but it had the missing element: calling that code back on the main queue! Here's the code:"
并且应用程序崩溃。为什么?好吧,搜索,我发现了我在上面提到的另一个问题,特别是支持我最初想法的公认答案,即简单地调用setViewControllers: animated:YES
,然后在setViewControllers: animated:NO
使用相同的视图控制器完成调用后立即重置UIPageViewController
,但它具有缺少元素:在主队列上调用该代码!这是代码:”
回答by Aron Balog
I fixed issue by setting edgesForExtendedLayout = UIRectEdgeNone
on my UIPageViewController
subclass:
我通过设置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;
}
回答by iVignesh
I also faced the same situation and my app has both swipe and next & previous buttons to navigate back and forth. To fix the issue assign a local Bool variable set it to true while initializing (let's say private var canScroll: Bool = true) then check for condition in first line of your navigation method using guard then set the Bool value to falsebefore setViewcontrollermethod. on completion of the animation set the same bool to trueso that when you perform a swipe action while the view controller is transitioning the guard statement checks for canScrollto be true if not it returns. that's how you can avoid the crash issue in pagination below is my code for next action.
我也遇到了同样的情况,我的应用程序有滑动和下一个和上一个按钮来来回导航。要解决此问题,请在初始化时分配一个本地 Bool 变量将其设置为 true(假设 private var canScroll: Bool = true)然后使用 guard 检查导航方法第一行中的条件,然后在setViewcontroller方法之前 将 Bool 值设置为false。在动画完成时,将相同的 bool 设置为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
})
}