online omnigroup omnifocus mac español ios objective-c iphone uikeyboard iphone-sdk-3.2

ios - omnigroup - UIKeyboardBoundsUserInfoKey está en desuso, ¿qué usar en su lugar?



omnifocus online (8)

@Jason, tu codificas si está bien, excepto por un punto.

En este momento no estás realmente animando nada y la vista simplemente se abrirá a su nuevo tamaño. Altura.

Tienes que especificar un estado desde el que animar. Una animación es una especie de (desde estado) -> (a estado) cosa.

Afortunadamente, existe un método muy conveniente para especificar el estado actual de la vista como (desde el estado).

[UIView setAnimationBeginsFromCurrentState:YES];

Si agrega esa línea justo después de beginAnimations: context: su código funciona perfectamente.

Estoy trabajando en una aplicación para iPad usando 3.2 SDK. Estoy tratando de obtener el tamaño del teclado para evitar que mis campos de texto se oculten detrás de él.

Recibo una advertencia en Xcode -> UIKeyboardBoundsUserInfoKey está en desuso. ¿Qué debo usar en lugar de eso para no recibir esta advertencia?



De la documentation para UIKeyboardBoundsUserInfoKey :

La clave para un objeto NSValue que contiene un CGRect que identifica los rectángulos del teclado en las coordenadas de la ventana. Este valor es suficiente para obtener el tamaño del teclado. Si desea obtener el origen del teclado en la pantalla (antes o después de la animación) use los valores obtenidos del diccionario de información del usuario a través de las constantes UIKeyboardCenterBeginUserInfoKey o UIKeyboardCenterEndUserInfoKey. Utilice en su lugar la clave UIKeyboardFrameBeginUserInfoKey o UIKeyboardFrameEndUserInfoKey.

Apple recomienda implementar una rutina de conveniencia como esta (que podría implementarse como una adición de categoría a UIScreen ):

+ (CGRect) convertRect:(CGRect)rect toView:(UIView *)view { UIWindow *window = [view isKindOfClass:[UIWindow class]] ? (UIWindow *) view : [view window]; return [view convertRect:[window convertRect:rect fromWindow:nil] fromView:nil]; }

para recuperar las propiedades de tamaño de marco de teclado ajustado a la ventana.

Tomé un enfoque diferente, que implica verificar la orientación del dispositivo:

CGRect _keyboardEndFrame; [[notification.userInfo valueForKey:UIKeyboardFrameEndUserInfoKey] getValue:&_keyboardEndFrame]; CGFloat _keyboardHeight = ([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortrait || [[UIDevice currentDevice] orientation] == UIDeviceOrientationPortraitUpsideDown) ? _keyboardEndFrame.size.height : _keyboardEndFrame.size.width;


El siguiente código soluciona un problema en la respuesta de Jay , que asume que UIKeyboardWillShowNotification no se UIKeyboardWillShowNotification nuevamente cuando el teclado ya esté presente.

Al teclear con el teclado japonés / chino, iOS dispara una UIKeyboardWillShowNotification adicional con el nuevo marco del teclado, aunque el teclado ya está presente, lo que lleva a que la altura de self.textView se reduzca por segunda vez en el código original.

Esto reduce el self.textView a casi nada. Entonces, es imposible recuperarse de este problema, ya que solo UIKeyboardWillHideNotification una única UIKeyboardWillHideNotification la próxima vez que se UIKeyboardWillHideNotification el teclado.

En lugar de restar / agregar altura a self.textView dependiendo de si el teclado se muestra / oculta como en el código original, el siguiente código simplemente calcula la altura máxima posible para self.textView después de restar la altura del teclado en la pantalla.

Esto supone que se supone que self.textView completa la vista completa del controlador de vista, y que no hay otra subvista que deba ser visible.

- (void)resizeTextViewWithKeyboardNotification:(NSNotification*)notif { NSDictionary* userInfo = [notif userInfo]; NSTimeInterval animationDuration; UIViewAnimationCurve animationCurve; CGRect keyboardFrameInWindowsCoordinates; [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve]; [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration]; [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardFrameInWindowsCoordinates]; [self resizeTextViewToAccommodateKeyboardFrame:keyboardFrameInWindowsCoordinates withAnimationDuration:animationDuration animationCurve:animationCurve]; } - (void)resizeTextViewToAccommodateKeyboardFrame:(CGRect)keyboardFrameInWindowsCoordinates withAnimationDuration:(NSTimeInterval)duration animationCurve:(UIViewAnimationCurve)curve { CGRect fullFrame = self.view.frame; CGRect keyboardFrameInViewCoordinates = [self.view convertRect:keyboardFrameInWindowsCoordinates fromView:nil]; // Frame of the keyboard that intersects with the view. When keyboard is // dismissed, the keyboard frame still has width/height, although the origin // keeps the keyboard out of the screen. CGRect keyboardFrameVisibleOnScreen = CGRectIntersection(fullFrame, keyboardFrameInViewCoordinates); // Max frame availble for text view. Assign it to the full frame first CGRect newTextViewFrame = fullFrame; // Deduct the the height of any keyboard that''s visible on screen from // the height of the text view newTextViewFrame.size.height -= keyboardFrameVisibleOnScreen.size.height; if (duration) { [UIView beginAnimations:nil context:nil]; [UIView setAnimationDuration:duration]; [UIView setAnimationCurve:curve]; } // Adjust the size of the text view to the new one self.textView.frame = newTextViewFrame; if (duration) { [UIView commitAnimations]; } }

Además, no olvide registrar las notificaciones del teclado en viewDidLoad:

- (void)viewDidLoad { [super viewDidLoad]; NSNotificationCenter* notifCenter = [NSNotificationCenter defaultCenter]; [notifCenter addObserver:self selector:@selector(resizeTextViewWithKeyboardNotification:) name:UIKeyboardWillShowNotification object:nil]; [notifCenter addObserver:self selector:@selector(resizeTextViewWithKeyboardNotification:) name:UIKeyboardWillHideNotification object:nil]; }

Acerca de dividir el código de cambio de tamaño en dos partes

La razón por la que el código de cambio de tamaño de TextView se divide en dos partes ( resizeTextViewWithKeyboardNotification: y resizeViewToAccommodateKeyboardFrame:withAnimationDuration:animationCurve: es para solucionar otro problema cuando el teclado persiste a través de un controlador de vista a otro (ver ¿Cómo detecto el teclado iOS? cuando se queda arriba entre los controladores? ).

Dado que el teclado ya está presente antes de que se empuje el controlador de vista, no hay notificaciones de teclado adicionales generadas por iOS y, por lo tanto, no hay forma de cambiar el tamaño de textView función de esas notificaciones de teclado.

El código anterior (así como el código original) que cambia el tamaño de self.textView solo funcionará cuando se muestre el teclado después de que se haya cargado la vista.

Mi solución es crear un singleton que almacene las últimas coordenadas del teclado, y en - viewDidAppear: del viewController, llame:

- (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; // Resize the view if there''s any keyboard presence before this // Only call in viewDidAppear as we are unable to convertRect properly // before view is shown [self resizeViewToAccommodateKeyboardFrame:[[UASKeyboard sharedKeyboard] keyboardFrame] withAnimationDuration:0 animationCurve:0]; }

UASKeyboard es mi singleton aquí. Lo ideal es que lo llamemos en - viewWillAppear: sin embargo, en mi experiencia (al menos en iOS 6), el convertRect:fromView: método que necesitamos usar en resizeViewToAccommodateKeyboardFrame:withAnimationDuration:animationCurve: no convierte correctamente el marco del teclado a la vista Coordenadas antes de que la vista sea totalmente visible.


Jugué con la solución ofrecida anteriormente pero aún tenía problemas. Esto es lo que se me ocurrió:

- (void)keyboardWillShow:(NSNotification *)aNotification { [self moveTextViewForKeyboard:aNotification up:YES]; } - (void)keyboardWillHide:(NSNotification *)aNotification { [self moveTextViewForKeyboard:aNotification up:NO]; } - (void) moveTextViewForKeyboard:(NSNotification*)aNotification up: (BOOL) up{ NSDictionary* userInfo = [aNotification userInfo]; // Get animation info from userInfo NSTimeInterval animationDuration; UIViewAnimationCurve animationCurve; CGRect keyboardEndFrame; [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve]; [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration]; [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardEndFrame]; // Animate up or down [UIView beginAnimations:nil context:nil]; [UIView setAnimationDuration:animationDuration]; [UIView setAnimationCurve:animationCurve]; CGRect newFrame = textView.frame; CGRect keyboardFrame = [self.view convertRect:keyboardEndFrame toView:nil]; newFrame.origin.y -= keyboardFrame.size.height * (up? 1 : -1); textView.frame = newFrame; [UIView commitAnimations]; }


Simplemente use la clave UIKeyboardFrameBeginUserInfoKey o UIKeyboardFrameEndUserInfoKey en lugar de UIKeyboardBoundsUserInfoKey


Simplemente utiliza este código:

//NSVale *aValue = [info objectForKey:UIKeyboardBoundsUserInfoKey]; //instead of Upper line we can use either next line or nextest line. //NSValue *aValue = [info objectForKey:UIKeyboardFrameEndUserInfoKey]; NSValue *aValue = [info objectForKey:UIKeyboardFrameBeginUserInfoKey];


- (CGSize)keyboardSize:(NSNotification *)aNotification { NSDictionary *info = [aNotification userInfo]; NSValue *beginValue = [info objectForKey:UIKeyboardFrameBeginUserInfoKey]; UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation]; CGSize keyboardSize; if ([UIKeyboardDidShowNotification isEqualToString:[aNotification name]]) { _screenOrientation = orientation; if (UIDeviceOrientationIsPortrait(orientation)) { keyboardSize = [beginValue CGRectValue].size; } else { keyboardSize.height = [beginValue CGRectValue].size.width; keyboardSize.width = [beginValue CGRectValue].size.height; } } else if ([UIKeyboardDidHideNotification isEqualToString:[aNotification name]]) { // We didn''t rotate if (_screenOrientation == orientation) { if (UIDeviceOrientationIsPortrait(orientation)) { keyboardSize = [beginValue CGRectValue].size; } else { keyboardSize.height = [beginValue CGRectValue].size.width; keyboardSize.width = [beginValue CGRectValue].size.height; } // We rotated } else if (UIDeviceOrientationIsPortrait(orientation)) { keyboardSize.height = [beginValue CGRectValue].size.width; keyboardSize.width = [beginValue CGRectValue].size.height; } else { keyboardSize = [beginValue CGRectValue].size; } } return keyboardSize; }