web-dev-qa-db-fra.com

Quelle est la vitesse d'animation du clavier apparaissant dans iOS8?

Ce qui suit est une animation pour un champ de texte et une barre d'outils qui se déplacent vers le haut lorsque le clavier apparaît.

    baseConstraint.constant = 211
    self.view.setNeedsUpdateConstraints()

    UIView.animateWithDuration(0.30, animations: {
        self.view.layoutIfNeeded()
        })

C'est proche mais pas tout à fait identique. Comment modifieriez-vous l'animation ci-dessus?

Modifier: 

Voici le code final en utilisant la réponse ci-dessous!

   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()
        })
}
19
user3784622

La réponse avec la durée variable est correcte et fonctionne iOS 3 à 8, mais avec la nouvelle version de Swift, le code de la réponse ne fonctionne plus . Peut-être que c'est une erreur de mon côté, mais je dois écrire:

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()
})

On dirait que objectForKey ne fonctionne plus et que la conversion est plus stricte.

17
Dam

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)
9
hojin

Mise à jour Swift 4, iOS 11+  

Enregistrez d'abord la notification dans la méthode du cycle de vie d'une vue:

override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(self, selector: #selector(keyBoardWillShow(notification:)), name: .UIKeyboardWillShow, object: nil)
}

Puis dans la méthode keyBoardWillShow:

@objc func keyBoardWillShow(notification: NSNotification) {
    guard let duration = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as? Double else {return}
    print(duration) // you got animation's duration safely unwraped as a double
}

Enfin, n'oubliez pas de supprimer observateur dans la méthode deinit:

deinit {
    NotificationCenter.default.removeObserver(self)
}
5
Skaal

Premièrement, la réponse choisie est la bonne voie à suivre.

Plus peut être fourni ici est ce que l'animation est vraiment. Si vous imprimez toutes les CAAnimations dans le bloc UIViewAnimation, vous constaterez que il s'agit d'un CASpringAnimation lorsque vous définissez la courbe d'animation sur celle fournie dans la notification au clavier. La durée est 0.5 et les autres paramètres sont:

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

Le code ci-dessus peut reproduire l'animation avec précision.

Une fois que la courbe d'animation est définie sur celle du clavier, l'animation UIView ignorera la durée du paramètre. (Si vous voulez vraiment changer la durée, ajustez la valeur mass.)

3
leavez

// tout d'abord déclarer un délégué dans votre classe UITextFieldDelegate

// Placer en haut du contrôleur de vue 

 // ****************** 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;
}
//

// Copie et contrôle la méthode déléguée de textfields dans votre classe

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.sharedApplication().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
}
1

Swift 4

 NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: .UIKeyboardWillShow, object: nil)

 func keyboardWillShow(notification: NSNotification) {
      let duration = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey]
      print("duration",duration)
 }
0
ZAFAR007
//--------------------------------------------------------------
// 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()
}
0
brian.clear

Je voudrais signaler quelque chose qui m'a fait trébucher tout en résolvant ce problème. J'avais besoin de la taille du clavier en raison de la nouvelle vue "quickype" et de sa capacité à afficher/masquer (iOS8 uniquement). Voici comment j'ai fini par le résoudre:

- (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
}];

}

0
Lucas Smith