My app that contains a UITableViewController embedded in UIPageViewController raises this exception from time to time:
Invalid parameter not satisfying: [views count] == 3
Backtrace:
* thread #1: tid = 0x6239fa, 0x03d1d88a libobjc.A.dylib`objc_exception_throw, queue = 'com.apple.main-thread, stop reason = breakpoint 25.3
frame #0: 0x03d1d88a libobjc.A.dylib`objc_exception_throw
frame #1: 0x0404f448 CoreFoundation`+[NSException raise:format:arguments:] + 136
frame #2: 0x03428fee Foundation`-[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 116
frame #3: 0x01e7c535 UIKit`-[_UIQueuingScrollView _replaceViews:updatingContents:adjustContentInsets:animated:] + 185
frame #4: 0x01e800ca UIKit`-[_UIQueuingScrollView _didScrollWithAnimation:force:] + 1231
frame #5: 0x01e7bb57 UIKit`-[_UIQueuingScrollView _scrollViewAnimationEnded:finished:] + 104
frame #6: 0x0190583c UIKit`-[UIScrollView(UIScrollViewInternal) animator:stopAnimation:fraction:] + 62
frame #7: 0x0197096e UIKit`-[UIAnimator stopAnimation:] + 533
frame #8: 0x0197100a UIKit`-[UIAnimator(Static) _advanceAnimationsOfType:withTimestamp:] + 325
frame #9: 0x01970b76 UIKit`-[UIAnimator(Static) _LCDHeartbeatCallback:] + 67
frame #10: 0x01663b8a QuartzCore`CA::Display::DisplayLinkItem::dispatch() + 48
frame #11: 0x01663a46 QuartzCore`CA::Display::DisplayLink::dispatch_items(unsigned long long, unsigned long long, unsigned long long) + 310
frame #12: 0x01663f6b QuartzCore`CA::Display::TimerDisplayLink::callback(__CFRunLoopTimer*, void*) + 123
frame #13: 0x0400dbd6 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 22
frame #14: 0x0400d5bd CoreFoundation`__CFRunLoopDoTimer + 1181
frame #15: 0x03ff5628 CoreFoundation`__CFRunLoopRun + 1816
frame #16: 0x03ff4ac3 CoreFoundation`CFRunLoopRunSpecific + 467
frame #17: 0x03ff48db CoreFoundation`CFRunLoopRunInMode + 123
frame #18: 0x0533b9e2 GraphicsServices`GSEventRunModal + 192
frame #19: 0x0533b809 GraphicsServices`GSEventRun + 104
frame #20: 0x01874d3b UIKit`UIApplicationMain + 1225
Does anyone have seen this already or have an idea what the reason could be?
Edit: after using this fix for more time, I can still see the bug on occasion so this isn't the complete fix (well... it was always kind of a hack). I'll update with the actual solution once I'll find it.
I've encountered this same error using UIPageViewController. After hours debugging the issue, I've found the cause was using UIView animations inside the completion handler of UIPageViewController's setViewControllers:direction:animated:completion:.
I don't know why animating at that stage causes the assertion error (I wasn't animating the UIPageViewController or its child view controllers), but wrapping the code block with dispatch_async on the main queue solves the issue and stop the crashing.
I saw this crash when trying to programmatically transition to a new page. An answer that made sense to me is to not allow them to touch the page view during the transition.
__block UIView *pageView = pageViewController.view;
// Disable page view to not allow the user to interrupt the page view animation and cause crash
pageView.userInteractionEnabled = NO;
[pageViewController setViewControllers:@[viewController] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:^(BOOL finished) {
if (finished) {
pageView.userInteractionEnabled = YES; // re-enable
}
}];
Just make sure you are not doing any animations within viewDidAppear in the controller that you are going back to. Or if you have to do it after some delay once the view has appeared.
I use UIPageViewController with Dots. After user swipes on the dots, the delegate didFinishAnimating get called and I trigger other animation, then it crashes. But it only happen when user swipes on the dots.
- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray<UIViewController *> *)previousViewControllers transitionCompleted:(BOOL)completed
{
if (completed && finished)
{
dispatch_async(dispatch_get_main_queue(), ^{
[self animateSomeView];
})
}
}
I encountered the same error with a UIViewController I had embedded in a UIPageViewController. In my case, I realized that my child controller had overridden viewWillAppear
and viewDidAppear
without calling through to super
. Although I can only guess at the details, it makes sense that doing so could mess up the view management. Adding the super
calls in made the problem go away.
In my case problem was in implementation of UIPageViewControllerDelegate
:
I update constraints in
pageViewController(_ pageViewController:, didFinishAnimating:, previousViewControllers:, transitionCompleted:)
dispatch_async
on main queue resolve this problem