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

Estoy recibiendo un mensaje de Advertencia en Xcode -> UIKeyboardBoundsUserInfoKey está en desuso ¿qué debo usar en lugar de no obtener esta advertencia?

InformationsquelleAutor Mikeware | 2010-05-11

9 Comentarios

  1. 87

    He jugado con la que anteriormente se ofrecían solución, pero todavía tenía problemas. He aquí lo que se me ocurrió lugar:

        - (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];
    }
    • Ustedes me salvó el día. Thank u!
    • Mientras que este código se trabaja generalmente, hay algunos romper condiciones. Por ejemplo, si el usuario tiene más de un teclado instalado y cambiar teclado usando el teclado internacional clave (que sólo se muestra si usted tiene más de un teclado instalado). Esto arrojará una UIKeyboardWillShowNotification, aunque el teclado ya está demostrado. El resultado será que su textField va a ser trasladado a otro de la altura del teclado de la pantalla. Esto ocurrirá cada vez que el teclado internacional se pulsa la tecla.
    • Estoy de acuerdo con Harkonian que usted necesita para establecer un BOOL que realiza un seguimiento de si ya hay un teclado que se muestra. Antes de UIKeyboardBoundsUserInfoKey, me había ofrecido una solución que es muy similar a la de Jason solución con la adición de los BOOL que siguió la pista de la presencia del teclado. Me gusta Jason solución, aunque. Muy limpio. stackoverflow.com/questions/1126726/…
    • Mi solución para que el Chino/Japonés problema con el teclado a continuación: stackoverflow.com/a/12953447/401329
    • ¿Qué acerca del uso de la animación de bloques en su lugar?
  2. 55

    De la documentación para UIKeyboardBoundsUserInfoKey:

    La clave para una NSValue objeto que contiene una CGRect que identifica los límites del rectángulo del teclado en la ventana de coordenadas. Este valor es suficiente para obtener el tamaño del teclado. Si usted desea conseguir el origen del teclado en la pantalla (antes o después de la animación) utilizar los valores obtenidos a partir de la información de usuario del diccionario a través de la UIKeyboardCenterBeginUserInfoKey o UIKeyboardCenterEndUserInfoKey constantes. Utilizar el UIKeyboardFrameBeginUserInfoKey o UIKeyboardFrameEndUserInfoKey clave en su lugar.

    Apple recomienda la implementación de una comodidad de rutina, tales como este (que podría ser implementado como una categoría, además 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 ventana ajustado teclado de tamaño de fotograma de propiedades.

    Me tomó un enfoque diferente, que implica la comprobación de 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;
    • Gracias Alex. Me fue muy difícil encontrar información sobre este tema, su respuesta seguramente será de ayuda en mi proyecto.
    • ¿De casualidad tienes un enlace a la recomendación por parte de Apple?
    • Llegué a dicha recomendación a través de una respuesta a un informe de error de entradas. No sé de donde usted encontrará que la información sea de dominio público, aunque.
    • Esta técnica no funcionará si la orientación de la pantalla no coincide con el de la orientación del dispositivo, así que no debería ser considerado como un propósito general de la solución.
    • He tenido algunos problemas de orientación con esto. Ahora soy simplemente tomando el mínimo de los dos «CGFloat _keyboardHeight = MIN(_keyboardEndFrame.tamaño.altura, _keyboardEndFrame.tamaño.ancho);», que funciona bien en mi caso.
    • cuál es la orientación problema ¿tienes ?

  3. 9

    Sólo tiene que utilizar 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];
    • Este tiene problemas cuando se gira el dispositivo. Ver a @AlexReynolds respuesta.
  4. 3

    El siguiente código corrige un problema en el Jay respuesta, que se supone que UIKeyboardWillShowNotification no se activará de nuevo cuando el teclado está ya presente.

    Al escribir con el Japonés/Chino teclado, iOS incendios extra UIKeyboardWillShowNotification con el teclado nuevo marco aunque el teclado ya está presente, que conducen a la altura de la self.textView ser reducidas por segunda vez en el código original.

    Esto reduce self.textView a casi nada. A continuación, se hace imposible para recuperarse de este problema, ya que vamos a esperar de una sola UIKeyboardWillHideNotification la próxima vez que el teclado es despedido.

    Vez 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 justo calcula la máxima altura posible para self.textView después de restar la altura del teclado en pantalla.

    Esto supone que self.textView se supone que debe llenar toda la vista del controlador de vista, y no hay otra vista que debe 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];
        }
    
    }

    También, 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 textView código de cambio de tamaño se divide en dos partes (resizeTextViewWithKeyboardNotification: y resizeViewToAccommodateKeyboardFrame:withAnimationDuration:animationCurve:) es solucionar el problema de otro cuando el teclado persiste a través de un empujón desde un punto de vista controlador a otro (ver ¿Cómo puedo detectar el teclado de iOS cuando se queda entre los controladores?).

    Desde el teclado ya está presente antes de que el controlador de vista es empujado, no hay teclado adicional notificaciones generadas por iOS, y por lo tanto no hay manera de cambiar el tamaño de la textView basado en esas notificaciones del teclado.

    El código de arriba (así como el código original) que cambia de tamaño self.textView así sólo funciona cuando se muestre el teclado después de el punto de vista ha sido cargado.

    Mi solución es crear un singleton que almacena el último teclado de coordenadas, y en - viewDidAppear: de la viewController, llame al:

    - (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í. Idealmente deberíamos llamar a este en - viewWillAppear:, sin embargo, en mi experiencia (al menos en iOS 6), el convertRect:fromView: método que debemos utilizar en resizeViewToAccommodateKeyboardFrame:withAnimationDuration:animationCurve: no se convierten correctamente el teclado de marco a la vista de coordenadas antes de que la vista es totalmente visible.

    • Esto es genial: muy pocos desarrolladores saber sobre el Japonés/Chino teclados y hacer el trabajo extra para dar cuenta de ellos.
    • Tengo un problema cuando este está en el paisaje, ya que reduce el ancho en lugar de la altura, pero por lo demás parece que funciona.
  5. 2

    Solo uso el UIKeyboardFrameBeginUserInfoKey o UIKeyboardFrameEndUserInfoKey clave en lugar de UIKeyboardBoundsUserInfoKey

  6. 1

    @Jason, código si bien, excepto por un punto.

    Por el momento no son en realidad la animación de la nada y a la vista de simplemente `pop’ a su nuevo tamaño.altura.

    Usted tiene que especificar un estado del que animar. Una animación es una especie de (de estado)->(para el estado) cosa.

    Por suerte no es un método conveniente para especificar el estado actual de la vista como el (de estado).

    [UIView setAnimationBeginsFromCurrentState:YES];

    Si se agrega que la línea de la derecha después de beginAnimations:contexto: el código funciona a la perfección.

    • Consulte la documentación de setAnimationsBeginsFromCurrentState: «Este método no hace nada, si una animación no está en vuelo o se invoca fuera de un bloque de animación. El valor predeterminado es NO.» Así que a menos que usted está haciendo algo fuera del ámbito normal de esta animación, no es necesario agregar el código. Cada vez que he utilizado este se anima bien
  7. 1
    - (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;
    }
  8. 0

    Su trabajado como este

    Esta es la restricción de que el botón guardar de la parte inferior

    @IBOutlet weak var saveBtnBottom: NSLayoutConstraint!
    @IBOutlet weak var nameText: UITextField!

    Dentro de viewDidLoad

    NotificationCenter.default.addObserver(self, selector: #selector(keyBoardWillShow(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(keyBoardWillHide(notification:)), name: UIResponder.keyboardWillHideNotification, object: nil)
    nameText.delegate = self

    Esta es de las funciones que necesitamos

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        nameText.resignFirstResponder()
        return true
    }
    
    
    @objc func keyBoardWillShow(notification: Notification){
        if let userInfo = notification.userInfo as? Dictionary<String, AnyObject>{
            let frame = userInfo[UIResponder.keyboardFrameEndUserInfoKey]
            let keyBoardRect = frame?.cgRectValue
            if let keyBoardHeight = keyBoardRect?.height {
                self.saveBtnBottom.constant = keyBoardHeight 
    
                UIView.animate(withDuration: 0.5, animations: {
                    self.view.layoutIfNeeded()
                })
            }
        }
    }
    
    @objc func keyBoardWillHide(notification: Notification){
        self.saveBtnBottom.constant = 30.0
        UIView.animate(withDuration: 0.5, animations: {
            self.view.layoutIfNeeded()
        })
    }

Dejar respuesta

Please enter your comment!
Please enter your name here