Переход UIPageViewController 'Несбалансированные вызовы для перехода к началу / концу отображения для'

Когда я перемещаюсь по UIPageViewController быстрее, чем его переходная анимация, я получаю « Unbalanced calls to begin/end appearance transitions for <MyDataViewController> », и одно из двух представлений в ландшафте не отображается, пока я не попытаюсь перевернуть страницу.

У кого-нибудь есть идея решить эту ошибку?

10 Solutions collect form web for “Переход UIPageViewController 'Несбалансированные вызовы для перехода к началу / концу отображения для'”

Вышеуказанные ответы были правильными, но я считаю более сложными, чем нужно, и кулинарная книга полезна. Итак, вот что, кажется, работает для меня:

В контроллере представления, который устанавливает и вызывает pageViewController, объявляет:

 @property (assign) BOOL pageIsAnimating; 

и в viewDidLoad:

  pageIsAnimating = NO; 

Добавь это:

 - (void)pageViewController:(UIPageViewController *)pageViewController willTransitionToViewControllers:(NSArray *)pendingViewControllers { pageIsAnimating = YES; } 

и добавьте пару строк:

 - (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed { if (completed || finished) // Turn is either finished or aborted pageIsAnimating = NO; ... } 

Жесты подавляются путем отказа от предоставления информации диспетчера просмотров:

 - (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController { if (pageIsAnimating) return nil; ... return after; } - (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController { if (pageIsAnimating) return nil; ... return before; } 

Ох, и изменения ориентации сбросят флаг:

 - (UIPageViewControllerSpineLocation)pageViewController:(UIPageViewController *)pageViewController spineLocationForInterfaceOrientation:(UIInterfaceOrientation)orientation { pageIsAnimating = NO; ... } 

Решается следующим образом:
1- Объявить флаг, указывающий, что анимация завершена или нет:

 BOOL pageAnimationFinished; 

2- Установите для этого флага значение true в viewDidLoad:

 pageAnimationFinished = YES; 

3- Отключить tapGesture для pageViewController и назначить 'self' делегату panGestureRecognizer:

 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- Разрешить / Запретить panGestureRecognizer через следующий метод делегирования распознавателя жестов:

 -(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- Добавьте следующий метод делегата viewController:

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

Хороший ответ от 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; } 

Я слишком много играл с ним и, похоже, это хорошее решение, которое хорошо работает.

Вот версия QUICK, использующая делегат:

добавьте этот код (убедитесь, что вы включили UIPageViewControllerDelegate в свой заголовок или расширение класса и назначили self.pageViewController.delegate = self; ):

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

затем проверьте self.pageAnimationFinished и верните self.pageAnimationFinished если это == NO .

Дольше Объяснение:

 - (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed 

Мы можем использовать этот метод делегата из UIPageViewControllerDelegate чтобы узнать, когда анимация перелистает или просматривает страницы. Используя это, мы можем реализовать его следующим образом:

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

то просто верните nil в своем

 - (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(PageViewController *)viewController 

а также

 - (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(PageViewController *)viewController 

когда

pageAnimationFinished == NO . Обязательно установите для параметра pageAnimationFinished значение NO при анимации. Лучший способ узнать, когда вы живете, – это использовать противоположность

 - (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed 

а именно:

 - (void)pageViewController:(UIPageViewController *)pageViewController willTransitionToViewControllers:(NSArray *)pendingViewControllers 

С тех пор я не видел этого предупреждения, и это можно сделать в 1/3 строк в качестве других решений. И намного проще следовать.

Вот версия Swift версии Билла Чесвика (в настоящее время главный ответ):

Добавьте переменную, чтобы сохранить текущее состояние:

 var pageIsAnimating = false 

Установите анимационное состояние:

 func pageViewController(pageViewController: UIPageViewController, willTransitionToViewControllers pendingViewControllers: [UIViewController]) { self.pageIsAnimating = true } func pageViewController(pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) { if finished || completed { self.pageIsAnimating = false } } 

Заблокируйте переходы, если они в настоящее время оживляют:

 func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? { if self.pageIsAnimating { return nil } // Your code here } func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? { if self.pageIsAnimating { return nil } // Your code here } 

Спасибо, Билл Чесвик!

Мое решение быстро, просто и эффективно:

  1. Установите делегат просмотра просмотра веб-сайта в свой класс
  2. Добавьте ниже код

     extension MyPageVC: UIPageViewControllerDelegate { func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) { self.view.isUserInteractionEnabled = false } func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) { self.view.isUserInteractionEnabled = true } } 

Как насчет этого:

 - (void)pageViewController:(UIPageViewController*)pgVC willTransitionToViewControllers:(NSArray*)pendingVCs { pgVC.dataSource = nil; // ... to disallow user to change pages until animation completes } - (void)pageViewController:(UIPageViewController*)pgVC didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray*)prevVCs transitionCompleted:(BOOL)completed { if(completed || finished) { pgVC.dataSource = _pgViewDataSource; // ... to allow user to change pages again } } 

Используйте методы UIPageViewControllerDelegate и настройте защиту, чтобы предотвратить создание новых просмотров страниц при обнаружении чрезмерных поворотов страниц.

  1. Вы можете отключить распознаватели жестов
  2. Установите «userInteraction» для отключения в UIView
  3. поддерживать флаг в UIPageViewController, чтобы игнорировать дальнейший ввод, когда происходит анимация. (предупреждение об этой опции .. ios5 и ios6 имеют разные способы определения, когда анимация началась ..)

Мне пришлось добавить его в viewDidAppear: чтобы он работал

  - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; self.pageAnimationFinished = YES; } 

Я буду пытаться игнорировать жест на UIPageViewControllers при переходе.

  • Предотвращение воздействия UIPageViewController на UISlider
  • UIPageViewController UIImage не показывает полный экран
  • UIPageViewController не позволяет выбрать uitextfield
  • Три слоя распознавателя жестов
  • Доступ к уже созданным контроллерам представлений в UIPageViewController
  • Добавление UIPageViewController в subview, subview показывает только край страницыContentview
  • как добавить два контроллера представления в UIPageViewcontroller
  • Индикатор страницы UIPageViewController
  • Событие кликов на экране PageViewController
  • Отсутствует указатель страницы в UIPageViewController
  • Использование программного обеспечения View Controller из раскадровки программно в контроллере просмотра страницы
  • Как удалить нижний зазор UIPageViewController
  • Interesting Posts

    Разработка модуля Appposerator IOS

    UITextField, UITextInputAssistantItem скрыть и с утечками в iOS

    Кнопки панели инструментов мигают (быстро затухают) при нажатии на контроллер просмотра анимированный

    Невозможно округлить колпачки в UIBezierPath Arc даже с kCGLineCapRound

    Определение того, будет ли представлен UIViewController

    Простая базовая анимация 3D-преобразование UIView

    Неверное решение GCD производителя-потребителя Apple doc?

    Встроенное видео vimeo в приложении iPhone с использованием iOS 6, не играющего

    ios, определяющий угол линии или степень

    OpenCV: случайные альфа-канальные артефакты при наложении изображений с прозрачностью в iOS

    Обнаружение последней ячейки UITableView

    Открытие файла импорта для модуля «CoreData»: разрешение отклонено

    Получение URL-адреса в SLComposeServiceViewController в расширенном расширении для Safari на iOS

    Core Location: лучшие практики для переключения между услугой значимого местоположения и службой стандартного местоположения?

    Точный шрифт Корана с Thajweed – ios

    PhoneC: Разработка iOS проста с помощью XCode, Swift3, UITableView, cocatouch, давайте создадим приложения для iPhone, iPad и Macbook.