UIScrollView ScrollRectToVisible – no funciona con animate = yes

Tengo un UIScrollView que contiene un button. Cuando se presiona el button, me gustaría desplazarme hasta la parte inferior de la vista usando scrollRectToVisible.

p.ej:

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

Si configuro animado a NO, todo funciona como se esperaba, pero si lo pongo en SÍ, veo un comportamiento realmente extraño:

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

Imprimí _geScroll_Settings.contentSize, y es como se esperaba.

También he intentado retrasar la llamada a scrollRectToVisible iniciando un timer, pero los resultados son más o less lo mismo.

El scrollView es bastante vainilla. Lo estoy creando en el generador de interfaces. Estoy agregando dinámicamente el contenido de scrollView al inicio, y ajustando su contenido size de manera apropiada, pero todo parece estar funcionando bien.

¿Alguna idea?

Mi apuesta es que scrollRectToVisible se está eliminando porque el área visible no es válida (1×1), o el desplazamiento en y está justo fuera de los límites, ¿ha intentado configurarlo con el tamaño del área visible de scrollView en su 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]; 

Lamento no poder ayudarte más, pero ahora mismo no estoy en mi Mac, así que no puedo hacer una testing. El código anterior crearía una CGRect del tamaño exacto de lo que encaja dentro de la porción visible de scrollView, y el desplazamiento sería la última porción visible en él.

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

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

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

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

 #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 
    Intereting Posts