2011-08-23 13 views
5

Tengo un UIScrollView que contiene un botón. Cuando se presiona el botón, me gustaría desplazarme hasta la parte inferior de la vista usando scrollRectToVisible.UIScrollView ScrollRectToVisible - no funciona con animate = yes

por ejemplo:

CGRect r = CGRectMake(0, myUIScrollView.contentSize.height - 1, 1, 1); 
[myUIScrollView scrollRectToVisible:r animated:YES]; 

si fijo animado a NO, todo funciona como se esperaba, pero si lo fijo a sí, ya veo comportamiento muy extraño:

  • básicamente, no pasa nada .
  • si toco el botón varias veces, puede desplazarse un par de píxeles, o puede desplazarse completamente.
  • pero si deslizo la vista manualmente con un dedo antes de presionar el botón, tiene la posibilidad de desplazarse hacia abajo como se esperaba, pero no es seguro.

He impreso _geScroll_Settings.contentSize, y es como esperaba.

También he intentado retrasar la llamada a scrollRectToVisible iniciando un temporizador, pero los resultados son prácticamente los mismos.

El scrollView es bastante vanilla. Lo estoy creando en el constructor de interfaz. Estoy agregando dinámicamente el contenido de scrollView al inicio y estoy ajustando su contenido de forma adecuada, pero todo parece funcionar bien.

¿Alguna idea?

+0

no han dado cuenta de esto, pero tengo que lograr que se haga, por lo que acaba de comenzar un temporizador y desplazarse por él mismo hasta que esté en el lugar correcto, usando setContentOffset w/animación: NO. funciona pero :( –

Respuesta

5

Mi apuesta es que scrollRectToVisible está cagando a cabo debido a que el área visible no es válida (1x1), o el desplazamiento Y es justo fuera de los límites, ¿ha intentado fijar con el tamaño del área visible de la ScrollView ¿en lugar?

CGRect rectBottom = CGRectZero; 
rectBottom.size = myUIScrollView.frame.size; 
rectBottom.origin.y = myUIScrollView.contentSize.height - rectBottom.size.height; 
rectBottom.origin.x = 0; 

[myUIScrollView scrollRectToVisible:rectBottom animated:YES]; 

Lo siento, no puedo ayudar más, pero no estoy en mi Mac en este momento, así que no puedo realizar una prueba. El código anterior crearía un CGRect del tamaño exacto de lo que cabe dentro de la porción visible de scrollView, y el desplazamiento sería la última porción visible en él.

+0

interesante. Lo probaré pero estoy dudoso. Usé rectángulos de tamaño más normal, por ejemplo, el ancho de scrollView y una altura mayor que uno pero menor que la altura de la vista de desplazamiento. pero no fue diferente. También probé rectángulos en el medio del contenido Tamaño en lugar de al final. Te lo haré saber. En una nota lateral, no sabía acerca de CGRectZero, ¡gracias! –

+0

solo estoy volviendo a ti el esto - lo intenté y no tuve suerte. Finalmente terminé animándome usando 'animado: NO' y un temporizador. Gracias de todos modos. –

+0

Me acabo de encontrar con esto. Pasé aproximadamente 2 horas mirando todo * pero * el scrollRectToVisible llamada. –

0

Encontré un problema similar, incluida la parte "Si configuro animado a NO, todo funciona como esperaba".

Resultó que en iOS 6 el UITextView auto desplaza a su padre UIScrollView más cercano para hacer que el cursor sea visible cuando se convierte en el primer respondedor. En iOS 7 no hay tal comportamiento. El UIScrollView parece confundirse por dos llamadas a scrollRectToVisible casi al mismo tiempo.

En iOS 6 mi llamada explícita a scrollRectToVisible se ignora la mayor parte del tiempo. Solo se desplazará para hacer que la primera línea de UITextView sea visible (el desplazamiento automático) y no todo como lo hace en iOS 7.

Para probarlo, cree una nueva aplicación de vista única en Xcode 5, configure su objetivo de despliegue a 6.0 y use el código a continuación para ViewController.m. Ejecútelo en el simulador de iOS 6.1, desplácese para hacer que el UITextView esté oculto y toque en cualquier lugar de la pantalla. Es posible que tenga que volver a intentarlo varias veces, pero en la mayoría de los casos solo hará que la primera línea sea visible.Si vuelve a habilitar el WORKAROUD, defina que UITextView se incrusta en su propio UIScrollView y que la llamada a scrollRectToVisible funciona como se espera.

#import "ViewController.h" 

//#define WORKAROUND 

@interface ViewController() 
@property (nonatomic, strong) UIScrollView *scrollView; 
@property (nonatomic, strong) UITextView *textView; 
@end 

@implementation ViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    [self.view addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(viewTap)]]; 

    self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 240)]; 
    self.scrollView.contentSize = CGSizeMake(320, 400); 
    self.scrollView.backgroundColor = [UIColor lightGrayColor]; 
    [self.view addSubview:self.scrollView]; 

#ifdef WORKAROUND 
    UIScrollView* dummyScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(20, 280, 280, 100)]; 
    self.textView = [[UITextView alloc] initWithFrame:dummyScrollView.bounds]; 
    [dummyScrollView addSubview:self.textView]; 
    [self.scrollView addSubview:dummyScrollView]; 
#else 
    self.textView = [[UITextView alloc] initWithFrame:CGRectMake(20, 280, 280, 100)]; 
    [self.scrollView addSubview:self.textView]; 
#endif 

    self.textView.backgroundColor = [UIColor grayColor]; 

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWasShown:) name:UIKeyboardDidShowNotification object:nil]; 
} 

- (void)dealloc 
{ 
    [[NSNotificationCenter defaultCenter] removeObserver:self]; 
} 

- (void)viewTap 
{ 
    if (self.textView.isFirstResponder) { 
     [self.textView resignFirstResponder]; 
    } 
    else { 
     [self.textView becomeFirstResponder]; 
    } 
} 

- (void)keyboardWasShown:(NSNotification*)aNotification 
{ 
#ifdef WORKAROUND 
    [self.scrollView scrollRectToVisible:CGRectInset(self.textView.superview.frame, 0, -10) animated:YES]; 
#else 
    [self.scrollView scrollRectToVisible:CGRectInset(self.textView.frame, 0, -10) animated:YES]; 
#endif 
} 

@end 
Cuestiones relacionadas