¿Cuál es la velocidad de animation del keyboard que aparece en iOS8?

La siguiente es una animation para un campo de text y una barra de herramientas que se mueven hacia arriba cuando aparece el keyboard.

baseConstraint.constant = 211 self.view.setNeedsUpdateConstraints() UIView.animateWithDuration(0.30, animations: { self.view.layoutIfNeeded() }) 

Está cerca, pero no es del todo idéntico. ¿Cómo modificarías la animation anterior?

Editar:

¡Aquí está el código final con la respuesta a continuación!

  func keyboardWillShow(aNotification: NSNotification) { let duration = aNotification.userInfo.objectForKey(UIKeyboardAnimationDurationUserInfoKey) as Double let curve = aNotification.userInfo.objectForKey(UIKeyboardAnimationCurveUserInfoKey) as UInt self.view.setNeedsLayout() baseConstraint.constant = 211 self.view.setNeedsUpdateConstraints() UIView.animateWithDuration(duration, delay: 0, options: UIViewAnimationOptions.fromMask(curve), animations: { self.view.layoutIfNeeded() }, completion: { (value: Bool) in println() }) } 

Puede get la duración de la animation y la curva de animation del dictionary userInfo en el keyboard Will Show: notifications.

Primero regístrate para la notificación

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

A continuación, obtenga los valores de las notifications userInfo keys.

 - (void)keyboardWillShow:(NSNotification*)notification { NSNumber *duration = [notification.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey]; NSNumber *curve = [notification.userInfo objectForKey: UIKeyboardAnimationCurveUserInfoKey]; // Do stuff with these values. } 

Hay muchas más de estas keys, y también puede getlas de la notificación UIKeyboardWillDismiss.

Esta funcionalidad está disponible desde iOS 3.0: D

Heres the docs:

https://developer.apple.com/library/ios/documentation/uikit/reference/UIWindow_Class/UIWindowClassReference/UIWindowClassReference.html#//apple_ref/doc/constant_group/Keyboard_Notification_User_Info_Keys

Avíseme si necesita ayuda para que funcione.

Versión Swift:

 NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillShow:", name: UIKeyboardWillShowNotification, object: nil) func keyboardWillShow(aNotification: NSNotification) { let duration = aNotification.userInfo.objectForKey(UIKeyboardAnimationDurationUserInfoKey) as NSNumber let curve = aNotification.userInfo.objectForKey(UIKeyboardAnimationCurveUserInfoKey) as NSNumber } 

La respuesta con la duración variable es correcta y funciona con iOS 3 a 8, pero con la nueva versión de Swift, el código de la respuesta ya no funciona. Tal vez sea un error de mi parte, pero tengo que escribir:

 let duration = aNotification.userInfo![UIKeyboardAnimationDurationUserInfoKey] as Double let curve = aNotification.userInfo![UIKeyboardAnimationCurveUserInfoKey] as UInt self.view.setNeedsLayout() //baseConstraint.constant = 211 self.view.setNeedsUpdateConstraints() UIView.animateWithDuration(duration, delay: 0.0, options: UIViewAnimationOptions(curve), animations: { _ in //self.view.layoutIfNeeded() }, completion: { aaa in //(value: Bool) in println() }) 

Parece que objectForKey ya no funciona y la conversión es más estricta.

swift3

  let duration = noti.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber let curve = noti.userInfo?[UIKeyboardAnimationCurveUserInfoKey] as! NSNumber self.view.setNeedsLayout() UIView.animate(withDuration: TimeInterval(duration), delay: 0, options: [UIViewAnimationOptions(rawValue: UInt(curve))], animations: { self.view.layoutIfNeeded() }, completion: nil) 

// en primer lugar, declarar delegado en su class UITextFieldDelegate

// Coloque en la parte superior del controller de vista

  // ****************** Keyboard Animation *************** var animateDistance = CGFloat() struct MoveKeyboard { static let KEYBOARD_ANIMATION_DURATION : CGFloat = 0.3 static let MINIMUM_SCROLL_FRACTION : CGFloat = 0.2; static let MAXIMUM_SCROLL_FRACTION : CGFloat = 0.8; static let PORTRAIT_KEYBOARD_HEIGHT : CGFloat = 216; static let LANDSCAPE_KEYBOARD_HEIGHT : CGFloat = 162; } // 

// Copiar y plagiar campos de text delegar el método en su class

 func textFieldDidBeginEditing(textField: UITextField) { let textFieldRect : CGRect = self.view.window!.convertRect(textField.bounds, fromView: textField) let viewRect : CGRect = self.view.window!.convertRect(self.view.bounds, fromView: self.view) let midline : CGFloat = textFieldRect.origin.y + 0.5 * textFieldRect.size.height let numerator : CGFloat = midline - viewRect.origin.y - MoveKeyboard.MINIMUM_SCROLL_FRACTION * viewRect.size.height let denominator : CGFloat = (MoveKeyboard.MAXIMUM_SCROLL_FRACTION - MoveKeyboard.MINIMUM_SCROLL_FRACTION) * viewRect.size.height var heightFraction : CGFloat = numerator / denominator if heightFraction > 1.0 { heightFraction = 1.0 } let orientation : UIInterfaceOrientation = UIApplication.shanetworkingApplication().statusBarOrientation if (orientation == UIInterfaceOrientation.Portrait || orientation == UIInterfaceOrientation.PortraitUpsideDown) { animateDistance = floor(MoveKeyboard.PORTRAIT_KEYBOARD_HEIGHT * heightFraction) } else { animateDistance = floor(MoveKeyboard.LANDSCAPE_KEYBOARD_HEIGHT * heightFraction) } var viewFrame : CGRect = self.view.frame viewFrame.origin.y -= animateDistance UIView.beginAnimations(nil, context: nil) UIView.setAnimationBeginsFromCurrentState(true) UIView.setAnimationDuration(NSTimeInterval(MoveKeyboard.KEYBOARD_ANIMATION_DURATION)) self.view.frame = viewFrame UIView.commitAnimations() } func textFieldDidEndEditing(textField: UITextField) { var viewFrame : CGRect = self.view.frame viewFrame.origin.y += animateDistance UIView.beginAnimations(nil, context: nil) UIView.setAnimationBeginsFromCurrentState(true) UIView.setAnimationDuration(NSTimeInterval(MoveKeyboard.KEYBOARD_ANIMATION_DURATION)) self.view.frame = viewFrame UIView.commitAnimations() } func textFieldShouldReturn(textField: UITextField) -> Bool { textField.resignFirstResponder() return true } 

Me gustaría señalar algo que me hizo tropezar al resolver este problema. Necesitaba el tamaño del keyboard debido a la nueva vista "rápida" y su capacidad de mostrar / ocultar (solo iOS8). Así es como terminé resolviéndolo:

 - (void)keyboardWillChangeFrame:(NSNotification *)notification { NSValue *value = notification.userInfo[UIKeyboardFrameEndUserInfoKey]; self.keyboardFrame = [value CGRectValue]; NSTimeInterval duration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]; [UIView animateWithDuration:duration animations:^{ //ANIMATE VALUES HERE }]; 

}

 //-------------------------------------------------------------- // MARK: - // MARK: - UITextFieldDelegate //-------------------------------------------------------------- //To trigger event when user types in fields //right click in IB and choose EditingChanged >> textField_EditingChanged //NOTE IF KEYBOARD NOT SHOWING IN SIMULATOR and no view appearing ITS TURNED OFF BY DEFAULT SO YOU CAN TYPE WITH YOUR MAC KEYBOARD - HIT CMD+K or Simulator > Menu > Toggle Software Keyboard... @IBAction func textField_EditingChanged(textField: UITextField) { //if more than one search if(textField == self.textFieldAddSearch){ appDelegate.log.error("self.textFieldAddSearch: '\(self.textFieldAddSearch.text)'") if textField.text == ""{ }else{ callJSONWebservices(textField.text) } }else{ appDelegate.log.error("textFieldDidBeginEditing: unhandled textfield") } } //TWO WAYS TO HIDE THE VIEW //textFieldShouldReturn //buttonCancel_Action //USER HIT RETURN BUTTON ON keyboard >> resignFirstResponder >> triggers keyboardWillHide func textFieldShouldReturn(textField: UITextField)-> Bool{ //triggers keyboardWillHide: which also fades out view self.textFieldAddSearch.resignFirstResponder() return false } //-------------------------------------------------------------- // MARK: - // MARK: - KEYBORAD //-------------------------------------------------------------- private func subscribeToKeyboardNotifications() { NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillShow:", name: UIKeyboardWillShowNotification, object: nil) NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillHide:", name: UIKeyboardWillHideNotification, object: nil) } private func unsubscribeFromKeyboardNotifications() { NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: nil) NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: nil) } func keyboardWillShow(notification: NSNotification) { if let userInfo = notification.userInfo { if let heightKeyboard = userInfo[UIKeyboardFrameEndUserInfoKey]?.CGRectValue().height { if let duration = userInfo[UIKeyboardAnimationDurationUserInfoKey]?.doubleValue { self.viewAddNewSearchResults.alpha = 0.0 self.viewAddNewSearchResults.hidden = false if let curve = userInfo[UIKeyboardAnimationDurationUserInfoKey]?.integerValue { appDelegate.log.info("keyboardWillShow: duration:\(duration)") UIView.animateWithDuration(duration, delay:0.0, options: .CurveEaseInOut, animations: { //self.view.frame = CGRectMake(0, 0, Geo.width(), Geo.height() - height) self.viewAddNewSearchResults_BottomConstraint.constant = heightKeyboard; self.viewAddNewSearchResults.alpha = 1.0 }, completion: nil) } } } } } func keyboardWillHide(notification: NSNotification) { if let userInfo = notification.userInfo { if let heightKeyboard = userInfo[UIKeyboardFrameEndUserInfoKey]?.CGRectValue().height { if let duration = userInfo[UIKeyboardAnimationDurationUserInfoKey]?.doubleValue { if let curve = userInfo[UIKeyboardAnimationDurationUserInfoKey]?.integerValue { appDelegate.log.info("keyboardWillHide: duration:\(duration)") UIView.animateWithDuration(duration, delay:0.0, options: .CurveEaseInOut, animations: { self.viewAddNewSearchResults_BottomConstraint.constant = 0; self.viewAddNewSearchResults.alpha = 0.0 }, completion: nil) } } } } } //Add button shows search result panel below search text fields //just set focus in the textField //then the keyboardWillShow will fade in the view and resize it to fit above the keyboard //and match fade in duration to animation of keyboard moving up @IBAction func buttonAdd_Action(sender: AnyObject) { //triggers keyboardWillHide: which also fades out view self.textFieldAddSearch.resignFirstResponder() } //TWO WAYS TO HIDE THE VIEW //textFieldShouldReturn //buttonCancel_Action //Cancel on the search results - just resignFirstResponder >> triggers keyboardWillHide: which also fades out view @IBAction func buttonCancel_Action(sender: AnyObject) { //triggers keyboardWillHide: which also fades out view self.textFieldAddSearch.resignFirstResponder() } 

En primer lugar, la respuesta seleccionada es el path correcto.

Más se puede proporcionar aquí es lo que realmente es la animation. Si imprime todas las Anomalías de CA en el bloque UIViewAnimation, encontrará que es un CASpringAnimation cuando configura la curva de animation a la proporcionada en la notificación del keyboard. La duración es 0.5 y otros parameters son:

 let ani = CASpringAnimation(keyPath: someKey) ani.damping = 500 ani.stiffness = 1000 ani.mass = 3 ani.duration = 0.5 

El código anterior puede reproducir la animation con precisión.

Una vez que la curva de animation se establece en el keyboard uno, la animation UIView ignorará la duración del parámetro. (Si realmente desea cambiar la duración, ajuste el valor de mass .)