UICollectionView llamando a scrollViewDidScroll: cuando aparece desde la pila de navegación


Tengo un controlador de navegación, su controlador de vista raíz es de tipo CollectionViewControllerA. Al seleccionar un elemento, tengo una animación de desvanecimiento y expansión seguida de una llamada para empujar un segundo controlador de vista de tipo CollectionVewControllerB en la pila:

CollectionViewControllerB *b = ... // construction of the view controller to be pushed
[UIView animateWithDuration:.3
                 animations:^{
                     self.collectionView.transform = CGAffineTransformMakeScale(1.5, 1.5);
                     self.collectionView.alpha = 0;
                 }
                 completion:^(BOOL s){
                     [self.navigationController pushViewController:b animated:NO];
                 }];

Hago estallar el controlador de vista de una manera similar

[UIView animateWithDuration:.3
                 animations:^{
                     self.collectionView.transform = CGAffineTransformMakeScale(.3, .3);
                     self.collectionView.alpha = 0;
                 }
                 completion:^(BOOL s){
                     [self.navigationController popViewControllerAnimated:NO];
                 }];

El problema aquí es que la aplicación se bloquea al hacer estallar el controlador de vista. Razón:

*** -[CollectionViewControllerB scrollViewDidScroll:]: message sent to deallocated instance

Entiendo que el problema se debe a que el controlador de vista emergente es destruido, pero ¿por qué scrollViewDidScroll: es llamado en primer lugar? Nada cambia el contentOffset del collectionView en el código, y tampoco hay interacción del usuario. A menos que cambiar la propiedad transform también active el método para ser llamado?

CollectionViewControllerB implementa scrollViewDidScroll: porque necesito desactivar el desplazamiento vertical.

Mientras tanto tengo un truco muy muy desordenado para evitar el accidente, es decir, antes de la animación, agrego

self.collectionView.delegate = nil;

Esto evita que el método sea llamado. Pero tiene que sería una mejor manera.

¿Puede alguien arrojar alguna luz sobre por qué scrollViewDidScroll: se llama y cómo se puede detener?

Author: Allen Zeng, 2013-03-05

3 answers

Parece Que la única manera de resolver el problema es lo que ya he hecho... establecer el delegado en nil antes de la animación.

self.collectionView.delegate = nil;

Esperemos que esto ayude a alguien más en el futuro.

 56
Author: Allen Zeng,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-25 05:07:18

Establece self.automaticallyAdjustsScrollViewInsets = NO; dentro de tu controlador de vista.

Tuve un problema similar a este, y encontré que al navegar fuera de la página, el contentOffset estaba cambiando por 20 cada vez.

Encontré que establecer esta propiedad dentro de mi controlador de vista detuvo este cambio, y por lo tanto scrollViewDidScroll ya no se llamaba. Resulta que el controlador de vista ajusta automáticamente las inserciones de contenido para los cambios en la barra de estado, la barra de navegación, etc.. incluso cuando navegas lejos.

Creo que esto es una mejor solución y explicación adecuada de por qué se llamaba al método de desplazamiento.

 9
Author: jack moseley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-08 09:17:06

Puede probar esto en su controlador .

[self setEdgesForExtendedLayout:UIRectEdgeNone];

Espero que esto te ayude.

 0
Author: wxhui,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-15 05:56:44