Problema con uiscrollview setcontentoffset animated no se desplaza cuando está animado: sí está configurado


Esto es muy extraño y me pregunto si alguien tiene algún pensamiento?

Estoy tratando de desplazar un UIScrollView en respuesta a una pulsación de botón en el iPad.

Si lo hago:

CGPoint currentOff = scrollView.contentOffset;
currentOff.x+=240;
[scrollView setContentOffset:currentOff animated: NO];

La vista de desplazamiento salta a la posición requerida como se esperaba, pero quiero que se desplace. Sin embargo, cuando lo hago:

CGPoint currentOff = scrollView.contentOffset;
currentOff.x+=240;
[scrollView setContentOffset:currentOff animated: YES];

Entonces no hace nada! Tengo otra vista de desplazamiento que funciona correctamente y responde a setContentOffset:YES como se esperaba, así que estoy bastante desconcertado. Cualquier idea sobre por qué el desplazamiento podría no suceda son bienvenidos!

Además, - (void)scrollViewDidScroll:(UIScrollView *)sender no recibe nada en absoluto cuando se usa animated:YES pero se invoca cuando se usa animated:NO!

Author: DarkDust, 2010-10-15

9 answers

Yo también hice esto y terminé haciendo esta solución:

[UIView animateWithDuration:.25 animations:^{
    self.scrollView.contentOffset = ...;
}];
 75
Author: Philippe Sabourin,
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
2012-03-09 16:45:31

Hablando desde la experiencia personal, este problema ocurre cuando setContentOffset: es llamado varias veces antes de que la animación haya tenido la oportunidad de ejecutarse.

No he rastreado totalmente el problema, pero creo que el problema es algo como esto:

SetContentOffset:animated recibe una llamada que establece el nuevo valor de desplazamiento. setContentOffset: posteriormente se llama con los mismos parámetros, lo que cancela la animación. También se da cuenta de que los nuevos parámetros son los igual que los parámetros antiguos, asume que no hay nada que hacer, aunque la animación no se haya ejecutado todavía.

La solución anterior de alguna manera rompe este ciclo, pero quizás una solución menos kludgy es poner puntos de interrupción en el código y eliminar las múltiples llamadas.

 7
Author: aepryus,
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-06-03 13:42:23

Difícil de decir con ese pedazo de código que diste. Y de hecho, si estás diciendo, que tienes un proyecto, donde todo está funcionando bajo las mismas condiciones, entonces obviamente las condiciones no son las mismas :) No pude reproducir el problema, pero aquí hay algunas suposiciones para 2 casos:

  1. Creación de UIScrollView con nib.

    • Simplemente no olvide crear IBOutlet y enlazarlo al elemento ScrollView en nib. En una aplicación basada en vista simple justo después que tengo ScrollView trabajando como deseabas en animación: SÍ y NO. Pero para hacer el trabajo

    -(void)scrollViewDidScroll:(UIScrollView *)sender; debe establecer el delegado:

yourScrollView.delegate = self;

Donde 'self' es la clase, donde tiene su función scrollViewDidScroll; por cierto, esta clase debe ajustarse al protocolo 'UIScrollViewDelegate'.

2.Creación del objeto UIScrollView manualmente.

  • Aquí la idea es básicamente la misma, así que voy a proporcionar algunos simples código:

    -(void) creatingScrollView {
        UIScrollView *newScroll = [[UIScrollView alloc] initWithFrame:CGRectMake(20, 5, 280, 44)];
        newScroll.pagingEnabled = YES;
        newScroll.showsVerticalScrollIndicator = NO;
        newScroll.showsHorizontalScrollIndicator = NO;
    
        // ... some subviews being added to our scroll view
    
        newScroll.delegate = self;
        [self.view addSubview:newScroll];
        [newScroll release];
    }
    

Esto funciona para mí. Espero que esto sea útil.

 2
Author: makaron,
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
2011-06-15 21:55:33

Solución para Xamarin.iOS

InvokeOnMainThread(() =>
{
  scrollView.SetContentOffset(new PointF((page * UIScreen.MainScreen.Bounds.Width), 0), true);
});

Esto también se puede resolver usando UIView.Animate

UIView.Animate(
    duration: .25,
    animation: () =>
    {
       scrollView.SetContentOffset(new PointF((value * UIScreen.MainScreen.Bounds.Width), 0), true);
    }
);
 1
Author: ben,
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-04-07 11:54:50

Puedes intentar:

[scrollView setContentOffset:CGPointMake(240, 0) animated:YES];
 0
Author: mtompson,
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
2011-03-08 12:37:28

Me enfrento al mismo problema que ScrollView no se desplaza. Y desactivé "Usar diseño automático" en la vista y luego el ScrollView funciona.

 0
Author: ChengChieh,
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
2014-05-26 03:58:50

Tuve el mismo problema, en mi caso también estaba interceptando:

- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {...}

Este método se llama inmediatamente después: (No espera hasta el final de la animación):

[scrollView setContentOffset:currentOff animated: YES];

Lo que significa que si tiene alguna lógica que "espera" el final de la animación e intercepta scrollViewDidEndScrollingAnimation, el resultado será indefinido, es decir: terminar la animación prematuramente.

EDITAR: La solución/solución aceptada:

[UIView animateWithDuration:.25 animations:^{
    self.scrollView.contentOffset = ...;
}];

También "funciona" en mi escenario porque establecer el contentOffset directamente no invoca scrollViewDidEndScrollingAnimation

 0
Author: Dado,
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
2014-08-06 18:52:34
func scrollViewDidScroll(scrollView: UIScrollView) {

    dispatch_async(dispatch_get_main_queue(),{

        UIView.animateWithDuration(0.10, animations: { () -> Void in

            let loginScrollViewCurrentPosition:CGPoint = CGPointMake(self.loginScrollView.contentOffset.x, self.loginScrollView.contentOffset.y) as CGPoint
            self.loginScrollView.setContentOffset(loginScrollViewCurrentPosition, animated: true)

            })
    })

}
 0
Author: A.G,
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-05-30 07:39:21

Estoy trabajando con tableviews, ya que la solución de aepryus dice: setContentOffset: se llama simultáneamente con otras animaciones.

En mi caso acabo de invertir estos comandos:

[tableView reloadData];
[tableView setContentOffset:CGPointMake(240, 0) animated:FALSE];

Así

[tableView setContentOffset:CGPointMake(240, 0) animated:FALSE];
[tableView reloadData];

La animación se inicia después de que el desplazamiento de contenido haya cambiado correctamente.

 0
Author: Marco,
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
2018-07-14 14:20:05