ios iphone debugging ios7 uipageviewcontroller

ios - Cómo resolver el error "Error al determinar la dirección de navegación para desplazamiento"



iphone debugging (2)

Mi error más frecuente es "No se pudo determinar la dirección de navegación para el desplazamiento" por razones, ¿alguna idea sobre cómo podría resolverlo?

Aquí está la última excepción Backtrace:

1. CoreFoundation __exceptionPreprocess + 131 2. libobjc.A.dylib _objc_exception_throw + 39 3. CoreFoundation +[NSException raise:format:] + 1 4. Foundation -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 91 5. UIKit __54-[_UIQueuingScrollView _didScrollWithAnimation:force:]_block_invoke + 221 6. UIKit -[_UIQueuingScrollView _didScrollWithAnimation:force:] + 567 7. UIKit -[_UIQueuingScrollView _scrollViewAnimationEnded:finished:] + 73 8. UIKit -[UIAnimator stopAnimation:] + 471 9. UIKit -[UIAnimator(Static) _advanceAnimationsOfType:withTimestamp:] + 285 10. UIKit -[UIAnimator(Static) _LCDHeartbeatCallback:] + 53 11. QuartzCore CA::Display::DisplayLinkItem::dispatch() + 99 12. QuartzCore CA::Display::DisplayLink::dispatch_items(unsigned long long, unsigned long long, unsigned long long) + 345 13. IOMobileFramebuffer IOMobileFramebufferVsyncNotifyFunc + 105 14. IOKit _IODispatchCalloutFromCFMessage + 249 15. CoreFoundation __CFMachPortPerform + 137 16. CoreFoundation __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 35 17. CoreFoundation __CFRunLoopDoSource1 + 347 18. CoreFoundation __CFRunLoopRun + 1399 19. CoreFoundation _CFRunLoopRunSpecific + 523 20. CoreFoundation _CFRunLoopRunInMode + 107 21. GraphicsServices _GSEventRunModal + 139 22. UIKit _UIApplicationMain + 1137 23. MyApp main (main.m:13)

ACTUALIZACIÓN: finalmente logré reproducir el error en el simulador, es cuando toco una vista y, al mismo tiempo, la animación de desplazamiento UIPageViewController comienza programáticamente. Básicamente, si configuraViewViewControllers programmatically con la animación configurada en sí y la animación de desplazamiento. Si toca cualquier parte de la pantalla antes de que comience la animación de desplazamiento, se producirá el siguiente bloqueo *** Error de aserción en - [_ UIQueuingScrollView _didScrollWithAnimation: force:], /SourceCache/UIKit/UIKit-2372/_UIQueuingScrollView.m:778 como se describe aquí .

También descargué la aplicación de muestra PhotoScroller de Apple y la edité con un cambio de página programático y tienen el mismo error.

Mi solución no fue activar el cambio de página si el usuario está tocando actualmente la pantalla, también puede cambiar la animación para curvar o eliminar la animación.


Como mencioné en la actualización de la pregunta, UIPageViewController parece bloquearse en las siguientes condiciones al final de la animación de la página de cambios:

  • Cambiar página programáticamente
  • El cambio de página está animado
  • TransitionStyle es igual a UIPageViewControllerTransitionStyleScroll
  • El usuario está tocando la pantalla cuando comienza el cambio de página

Pude reproducir el error en la aplicación de muestra PhotoScroller de Apple, simplemente agregando un cambio de página programática. Entonces el error parece ser culpa de Apple.

Como no pude resolver el error, eliminé una de las condiciones que activan el error (esperando una mejor solución). No estaba bien con el uso de una transición curl (UIPageViewControllerTransitionStyleCurl) o la eliminación de la animación de transición. Ambas soluciones funcionan. Entonces, cuando el usuario está tocando la pantalla, no activa el cambio de página programática con la siguiente línea

UIViewController* currentViewController = [self.viewControllers objectAtIndex:0]; if(currentViewController.view.isBeingTouch){ ContentViewController *nextViewController = [[ContentViewController alloc] init]; NSArray *viewControllers =; [self setViewControllers: @[loadingController] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:NULL]; }

Con currentViewController.view es una subclase de UIView que implementa la siguiente propiedad en el encabezado

@property (nonatomic, assign) BOOL isBeingTouch;

y los siguientes métodos en main

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ _isBeingTouch = YES; [super touchesBegan:touches withEvent:event]; } - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event{ _isBeingTouch = NO; [super touchesCancelled:touches withEvent:event]; } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{ _isBeingTouch = NO; [super touchesEnded:touches withEvent:event]; } -(BOOL)isBeingTouch{ for (UIView * view in self.subviews){ if([view isKindOfClass:[UIButton class]]) { UIButton * b = (UIButton *) view; if(b.isHighlighted) return YES; } } return _isBeingTouch; }

Solo tengo botones como subvistas, por lo que funciona para la mayoría de los casos. Sin embargo, podría haber una solución más completa


Idealmente, nos gustaría saber si el UIScrollView subyacente se está arrastrando o desacelerando. Pero Apple no permite el acceso público a UIScrollView en el controlador de página, por lo que podemos realizar un seguimiento del estado de transición del controlador de la página con un BOOL a través de estos dos delegados.

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

En su código para hacer una transición programática de las vistas de página, solo proceda si el controlador de página no está en transición.

if (!self.isTransitioning) { [self.pageController setViewControllers:@[toViewController] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil]; }