iOS11 UIPageViewController error 해결
iOS11 배포 이후 fabric에 관련 crash가 들어오기 시작했다
UIKit
-[UIPageViewController queuingScrollView:willManuallyScroll:toRevealView:concealView:animated:]
|
0 |
CoreFoundation |
__exceptionPreprocess |
|
1 |
libobjc.A.dylib |
objc_exception_throw |
|
2 |
CoreFoundation |
+[NSException raise:format:] |
|
3 |
Foundation |
-[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] |
|
4 |
UIKit |
-[UIPageViewController queuingScrollView:willManuallyScroll:toRevealView:concealView:animated:] |
|
5 |
UIKit |
-[_UIQueuingScrollView _notifyDelegateWillManuallyScroll:toRevealView:concealingView:animated:] |
|
6 |
UIKit |
__54-[_UIQueuingScrollView _didScrollWithAnimation:force:]_block_invoke |
|
7 |
UIKit |
-[_UIQueuingScrollView _didScrollWithAnimation:force:] |
|
8 |
UIKit |
-[_UIQueuingScrollView layoutSubviews] |
|
9 |
UIKit |
-[UIView(CALayerDelegate) layoutSublayersOfLayer:] |
|
10 |
QuartzCore |
-[CALayer layoutSublayers] |
|
11 |
QuartzCore |
CA::Layer::layout_if_needed(CA::Transaction*) |
|
12 |
QuartzCore |
CA::Context::commit_transaction(CA::Transaction*) |
|
13 |
QuartzCore |
CA::Transaction::commit() |
|
14 |
QuartzCore |
CA::Display::DisplayLink::dispatch_items(unsigned long long, unsigned long long, unsigned long long) |
|
15 |
IOKit |
IODispatchCalloutFromCFMessage |
|
16 |
CoreFoundation |
__CFMachPortPerform |
|
17 |
CoreFoundation |
__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ |
|
18 |
CoreFoundation |
__CFRunLoopDoSource1 |
|
19 |
CoreFoundation |
__CFRunLoopRun |
|
20 |
CoreFoundation |
CFRunLoopRunSpecific |
|
21 |
GraphicsServices |
GSEventRunModal |
|
22 |
UIKit |
UIApplicationMain |
그래서 구글링 한 결과

UIPageViewController navigates to wrong page with Scroll transition style
My UIPageViewController was working fine in iOS 5. But when iOS 6 came along, I wanted to use the new scroll transition style (UIPageViewControllerTransitionStyleScroll) instead of the page curl st...
stackoverflow.com
위 링크에 따르면 error는 PageViewController 의 일종의 버그이며, PageViewController의 animation 처리때문이었고, animation을 YES로 했을 때 pageviewcontroller가 가지는 내부 캐싱과 꼬이는 현상때문이라고 판단했다
이럴 땐
[Objective - C]
__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
});
}
}];
[Swift]
pageViewController.setViewControllers([page], direction: direction, animated: true) { done in
if done {
dispatch_async(dispatch_get_main_queue()) {
self.pageViewController.setViewControllers([page], direction: direction, animated: false, completion: {done in })
}
}
}
block처리를 통해 animation callback 을 받아 처리하거나,
if (transitionInProgress_ == NO) {
transitionInProgress_ = YES;
[self.pageViewController setViewControllers: viewControllers
direction:UIPageViewControllerNavigationDirectionForward
animated:isAnimated
completion:^(BOOL finished) {
transitionInProgress_ = !finished;
}];
}
이와같이 bool 값을 주어 처리하면 해결된다.