Хороший ответ из Basem Saadawy, но он имеет некоторый дефект.
На самом деле, вызов делегатаRecognizerShouldBegin: может быть вызван без дальнейшей анимации. Это возможно, если вы начинаете свой жест движением вертикального пальца, а его горизонтальное смещение недостаточно для запуска анимации (но этого достаточно, чтобы запустить gestureRecognizerShouldBegin: ). Таким образом, наша переменная pageAnimationFinished будет установлена в NO без реальной анимации. Поэтому pageViewController: didFinishAnimating: никогда не будет вызываться, и вы можете заблокировать текущую страницу без возможности ее изменения.
Вот почему лучше назначить NO этой переменной - это метод действия распознавателя жестов с экзаменом (нас интересует только горизонтальное направление).
Итак, последние шаги:
1) Объявить переменную экземпляра (флаг):
BOOL pageAnimationFinished;
2) Задайте свое начальное значение
- (void)viewDidLoad
{
[super viewDidLoad];
...
pageAnimationFinished = YES;
}
3) Назначьте делегат и пользовательское действие распознающим жестам
for (UIGestureRecognizer * gesRecog in self.pageViewController.gestureRecognizers)
{
if ([gesRecog isKindOfClass:[UIPanGestureRecognizer class]])
{
gesRecog.delegate = self;
[gr addTarget:self action:@selector(handlePan:)];
}
}
3 ') Анимация действительно начинается, когда перевод жестов больше в горизонтальном направлении, и палец движется горизонтально в одно мгновение. Я предполагаю, что одна и та же логика используется во внутреннем распознавателе, назначаемом UIPageViewController .
- (void) handlePan:(UIPanGestureRecognizer *)gestureRecognizer
{
if (pageAnimationFinished && gestureRecognizer.state == UIGestureRecognizerStateChanged)
{
CGPoint vel = [gestureRecognizer velocityInView:self.view];
CGPoint tr = [gestureRecognizer translationInView:self.view];
if (ABS(vel.x) > ABS(vel.y) && ABS(tr.x) > ABS(tr.y))
pageAnimationFinished = NO; // correct place
}
}
4) Запрет жестов, если анимация еще не закончена.
-(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;
}
return YES;
}
5) Анимация закончена
- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed
{
pageAnimationFinished = YES;
}
Я слишком много играл с ней и, похоже, это хорошее решение, которое хорошо работает.