0

I have two buttons which can be used to start the page transition in a UIPageViewController. I start the transition from one page to another programmatically like this:

//to go left
[_pageVC setViewControllers:@[[self pageViewController:_pageVC viewControllerBeforeViewController:[_pageVC.viewControllers lastObject]]]
                      direction:UIPageViewControllerNavigationDirectionReverse
                       animated:YES
                     completion:^(BOOL finished) { }];

The problems is that the position of the buttons make it very easy to tap them several times fast, which causes unwanted behaviour and even crashes the app. So I would like to deactivate them while the pages are transitioning.

For that purpose I created a BOOL, which I set to YES when the animation starts, but I do not know where to set it to NO again. The completition block in the function above is called too early and pageViewController:didFinishAnimating:previousViewControllers:transitionCompleted: does not get called if the transition was started programatically (from the docs: Called after a gesture-driven transition completes).

How can I deactivate the buttons while the transition is being executed?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Daniel
  • 20,420
  • 10
  • 92
  • 149
  • 1
    Can you fire something from the `ViewDidAppear` of the view controller you are transitioning to? I think that method only fires once the VC is fully on screen. – pbasdf Nov 13 '14 at 17:25
  • @pbasdf Yes, but I would rather make the contained VCs implementation independent from the page controller. But right now, yours is the best idea. Thank you. – Daniel Nov 17 '14 at 08:45

2 Answers2

0

I have used the solution from pbasdf to disable the buttons, but it probably was already working correctly. I realised that the problem wasn't so much the disabling of the buttons, but that the swiping was still active, causing strange behaviour.

I disable and enable the swiping when the buttons are enabled/disabled with this method:

-(void)setPVScrollEnabled:(BOOL)scrollEnabled
{
    for (UIScrollView *view in self.pageViewController.view.subviews) {

        if ([view isKindOfClass:[UIScrollView class]]) {

            view.scrollEnabled = scrollEnabled;
        }
    }
}
Community
  • 1
  • 1
Daniel
  • 20,420
  • 10
  • 92
  • 149
0

Add a time-out. Disable your buttons for example for 0.5 second:

self.buttonNext.enabled = NO;  
self.buttonPrev.enabled = NO;

[_pageVC setViewControllers:@[[self pageViewController:_pageVC viewControllerBeforeViewController:[_pageVC.viewControllers lastObject]]]
                      direction:UIPageViewControllerNavigationDirectionReverse
                       animated:YES
                     completion:nil];

  __weak YourClass *weakSelf = self;
  dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{  
  weakSelf.buttonNext.enabled = YES;  
  weakSelf.buttonPrev.enabled = YES;  
});
orkenstein
  • 2,810
  • 3
  • 24
  • 45
  • Adding a timeout is a very ugly solution, you cannot know how long it will take. I prefer the solution with viewDidAppear. – Daniel Nov 17 '14 at 10:45