Basem Saadawy Basem Saadawy - 6 months ago 131
iOS Question

UIPageViewController transition 'Unbalanced calls to begin/end appearance transitions for '

When I navigate through

UIPageViewController
faster than its transition animation I am getting '
Unbalanced calls to begin/end appearance transitions for <MyDataViewController>
' and one of the two views in landscape isn't shown until I try to turn the page.

Anybody has an idea to solve this bug?

Answer

Solved following these steps:
1- Declare a flag to indicate that the animation has finished or not:

BOOL pageAnimationFinished;

2- Set this flag to true in viewDidLoad:

pageAnimationFinished = YES;

3- Disable tapGesture for the pageViewController and assign 'self' to panGestureRecognizer delegate:

for (UIGestureRecognizer * gesRecog in self.pageViewController.gestureRecognizers)
{
    if ([gesRecog isKindOfClass:[UITapGestureRecognizer class]])
        gesRecog.enabled = NO;
    else if ([gesRecog isKindOfClass:[UIPanGestureRecognizer class]])
        gesRecog.delegate = self;
}

4- Allow/Disallow panGestureRecognizer through the following gesture recognizer delegate method:

-(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
    if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]] && ([gestureRecognizer.view isEqual:self.view] || [gestureRecognizer.view isEqual:self.pageViewController.view]))
    {
        UIPanGestureRecognizer * panGes = (UIPanGestureRecognizer *)gestureRecognizer;
        if(!pageAnimationFinished || (currentPage < minimumPage && [panGes velocityInView:self.view].x < 0) || (currentPage > maximumPage && [panGes velocityInView:self.view].x > 0))
            return NO;
        pageAnimationFinished = NO;
    }
    return YES;
}

5- Add the following pageViewController delegate method:

- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed
{
    pageAnimationFinished = YES;
}