19

I have a UIPageViewController that works as expected. I can scroll left and right and the delegate method didFinishAnimating is called when I scroll each direction. However, if I scroll too quickly I end up on a page where didFinishAnimating is not called, though it is called for all previous pages. Does anyone know why this might be happening?

I would think that didFinishAnimating would be called on every page transition regardless (e.g., even if the turn was aborted).

mattnedrich
  • 7,577
  • 9
  • 39
  • 45
  • 6
    I've been investigating this issue for a while and it appears likely it's a bug in the UIPageViewController implementation. I'm debating get rid of UIPageViewController and using a custom UIScrollView implementation to get around this bug. – Matt R Sep 14 '14 at 06:19
  • 1
    It's good to know that someone else was able to reproduce this behavior. – mattnedrich Sep 14 '14 at 20:31
  • hi did you get any workaround for this? – Arslan Asim Oct 28 '18 at 13:25

2 Answers2

14

This bug is still here in 2017.. I tried many alternative ways.. now I gave up the hope that this will be fixed by Apple and I think the best way is to use protocol to bound UIPageViewController with content ViewController, so we can notify UIPageViewController in viewDidAppear()

xiaoyu
  • 2,369
  • 2
  • 13
  • 15
  • i had the same issue, i was initialising and assigning `dataSource` and the `delegate` in a same block of code and i noticed that `delegate` methods were not called. Then i assigned `dataSource` while initialising and `delegate` after a background process it was calling `delegate` methods. its a strange bug i guess they(Apple) broke it in 2017. – Pratik Jamariya Jun 02 '17 at 07:56
2

I've got the same issue. I tried to use the UIScrollView delegate instead of UIPageViewController to solve the issue. This is a tricky method, not recommend to use.

1.get the UIScrollView in UIPageViewController to set delegate:

for (UIView *view in self.view.subviews) {
    if ([view isKindOfClass:[UIScrollView class]]) {
        UIScrollView *scroll = (UIScrollView *) view;
        scroll.delegate = self;
    }
}

2.override scrollViewWillBeginDragging:(UIScrollView *)scrollView

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
    [[NSNotificationCenter defaultCenter] postNotificationName:PageSwitchingBegan
                                                    object:nil];
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
    [[NSNotificationCenter defaultCenter] postNotificationName:PageSwitchingEnded
                                                    object:nil];
}

You may also try override - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView instead of scrollViewDidEndDragging to achieve better result.

chakming
  • 390
  • 5
  • 18
  • 1
    This implementation did not cater the situation that people tap on the pageControl dots to switch pages. So you may still need to implement `UIPageViewControllerDelegate` on `willTransitionToViewControllers` and `didFinishAnimating` – chakming Feb 04 '15 at 01:12