UIScrollView scrollRectToVisible: animado: no teniendo en count la rect en iOS7

[self.scrollView scrollRectToVisible:rect animated:YES]; 

¿Alguien tiene una pista de por qué esto funciona perfectamente en iOS6.1 y en iOS7.0.4 siempre se desplaza al UITextField que se ha convertido en el primer respondedor sin importar qué tipo de rectificación envíe como argumento?

 CGRect rect = CGRectMake(0, self.scrollView.frame.size.height - 1, 320, 1); [self.scrollView scrollRectToVisible:rect animated:YES]; 

Este código desplazará el UIScrollView a su parte inferior cuando se muestre el keyboard debido a que un UITextField dentro de UIScrollView se ha convertido en el primero en responder en iOS6.1 pero en iOS7.0.4 se desplaza para que el UITextFiled sea visible en su lugar.

Como lo veo, el UIScrollView en el SDK de iOS7 no importa qué, los autoscrolls a lo que se ha convertido en el primer respondedor dentro de él cuando scrollRectToVisible: animated: se llama.

Sospecho que la mayoría de ustedes, los desarrolladores están utilizando scrollRectToVisible:Animated: junto con las notifications del keyboard del sistema, tal como se explica en Apple Docs aquí . Para mí, el código de muestra provisto por Apple no funcionó (bueno, solo la mitad lo hizo).

Poner la llamada de método dentro de un bloque de envío me solucionó el problema:

 dispatch_async(dispatch_get_main_queue(), ^{ [self.scrollView scrollRectToVisible:rect animated:YES]; }); 

No entiendo completamente por qué esto funciona y no estoy seguro de si esto es 100% seguro, pero por otro lado se siente mucho más seguro que simplemente retrasar la llamada en 0.1 segundos como se sugiere en otra respuesta de Rikkles .

No soy un experto en problemas de subprocesss (aún), pero parece que cualquier método de sistema oculto anula el comportamiento de desplazamiento ya está en la queue principal cuando se envía UIKeyboardDidShowNotification . Entonces, si ponemos nuestra llamada de método en la queue principal también se ejecutará después y, por lo tanto, producirá el efecto deseado. (Pero eso es solo una suposition).

En iOS 8 (y posiblemente 7), el sistema operativo se copy automáticamente en UITextField al final de la operación de ejecución, justo antes de volver a escuchar la input del usuario. No encontré ninguna forma de ingresar después del desplazamiento automático del sistema operativo y antes de la input del usuario. Ni UIKeyboardWillShowNotification ni UIKeyboardDidShowNotification son ganchos que funcionarán.

Sin embargo, lo que siempre funcionará es el buen truco de realizar un selector después de la demora. Simplemente coloque el código de desplazamiento en su propio método y llame a ese método de la siguiente manera:

 - (void)keyboardDidShow:(NSNotification*)aNotification { // ... all code to choose the view you want ... [self performSelector:@selector(moveToView:) withObject:visibleView afterDelay:0.1]; } - (void)moveToView:(UIView *)aView { [self.scView scrollRectToVisible:aView.frame animated:YES]; } 

Y eso se ejecutará después de que el sistema operativo se grabe automáticamente y seas dorado.

Conocí este problema antes. No es fácil, pero aburrido seguro.

Fue porque establecí contentSize en 0 (porque no quieres que se desplace). Y debe configurar al less 1.

 [scrollView setContentSize: CGSizeMake(1, self.view.frame.size.height)]; 

Espero que sea la solución;)

Encontré una solución a este problema, pero no es bonito. Para desplazar la vista de desplazamiento a la location deseada, debe registrarse para las notifications keyboardWillShow y keyboardDidShow. A continuación, el código para configurar las inserciones de la vista de desplazamiento se coloca en el selector del observador de keyboard, y el código para desplazar la vista de desplazamiento a la location deseada se coloca en el selector del observador de keyboardDidShowNotification. Esto es lo que tengo:

Vista interiorDidLoad:

 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil]; 

Métodos de notificación:

 - (void) keyboardWillShow: (NSNotification*) aNotification; { NSDictionary* info = [aNotification userInfo]; CGSize kbSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size; float kbHeight = kbSize.height < kbSize.width ? kbSize.height : kbSize.width; UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbHeight, 0.0); _scrollView.contentInset = contentInsets; _scrollView.scrollIndicatorInsets = contentInsets; } -(void)keyboardDidShow:(NSNotification*)notification { CGRect aRect = CGRectMake(0, 0, _scrollView.frame.size.width, _scrollView.frame.size.height - _scrollView.frame.origin.y - self.scrollView.contentInset.bottom); CGRect scrollFrame = CGRectMake(self.loginView.frame.origin.x + self.loginButton.frame.origin.x, self.loginView.frame.origin.y + self.loginButton.frame.origin.y, self.loginButton.frame.size.width, self.loginButton.frame.size.height); if (!CGRectContainsRect(aRect, scrollFrame)) { [_scrollView scrollRectToVisible:scrollFrame animated:YES]; } }