iOS8中出现的键盘动画速度是多少?

时间:2014-07-24 00:09:12

标签: ios objective-c swift ios8

以下是textField和toolBar的动画,当键盘出现时,它会向上移动。

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

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

它很接近但不完全相同。你会如何修改上面的动画?

编辑:

以下是使用以下答案的最终代码!

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

10 个答案:

答案 0 :(得分:25)

您可以通过keyboardWillShow:notifications上的userInfo字典获取动画持续时间和动画曲线。

首先注册通知

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

然后从通知userInfo键中获取值。

- (void)keyboardWillShow:(NSNotification*)notification {
    NSNumber *duration = [notification.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey];
    NSNumber *curve = [notification.userInfo objectForKey: UIKeyboardAnimationCurveUserInfoKey];

   // Do stuff with these values.
}

这些密钥中有很多,你也可以从UIKeyboardWillDismiss通知中获取它们。

此功能一直可用于iOS 3.0:D

继承人的文件:

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

如果您需要帮助,请告知我们。

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
}

答案 1 :(得分:17)

可变持续时间的答案是正确的,并且工作iOS 3到8,但是使用新版本的Swift,答案的代码不再起作用了。 也许这是我的错误,但我必须写:

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

看起来objectForKey不再起作用,转换更严格。

答案 2 :(得分:9)

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)

答案 3 :(得分:5)

Swift 4更新,iOS 11 +

首先在视图的生命周期方法中注册通知:

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

然后在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
}

最后,不要忘记在deinit方法中删除观察者:

deinit {
    NotificationCenter.default.removeObserver(self)
}

答案 4 :(得分:3)

首先,选择的答案是正确的方法。

这里可以提供更多动画真实的内容。如果您在UIViewAnimation块中打印所有CAAnimations,则在将动画曲线设置为键盘通知中提供的曲线时,您会发现它是CASpringAnimation 。持续时间为0.5,其他参数为:

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

上面的代码可以精确地再现动画。

一旦将动画曲线设置为键盘,UIView动画将忽略参数中的持续时间。 (如果您确实要更改持续时间,请调整mass值。)

答案 5 :(得分:1)

//首先在类UITextFieldDelegate

中声明委托

//放置在视图控制器的顶部

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

//复制和害虫文本字段委托您班级的方法

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
}

答案 6 :(得分:1)

Swift 5解决方案

let duration = notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as! Double
let curve = notification.userInfo![UIResponder.keyboardAnimationCurveUserInfoKey] as! UInt

UIView.animate(
       withDuration: duration,
       delay: 0.0,
       options: UIView.AnimationOptions(rawValue: curve),
       animations: {
           self.view.layoutIfNeeded()
       }
)

答案 7 :(得分:0)

我想指出在解决这个问题时绊倒我的事情。由于新的“快速”视图及其显示/隐藏功能(仅限iOS8),我需要键盘的大小。这就是我最终解决它的方法:

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

}

答案 8 :(得分:0)

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

答案 9 :(得分:0)

Swift 5的正确解决方案

NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChange), name: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil)

然后

@objc func keyboardWillChange(notification: NSNotification) {

    guard let userInfo = notification.userInfo else { return }

    let duration = userInfo[UIKeyboardAnimationDurationUserInfoKey] as! Double
    let curve = userInfo[UIKeyboardAnimationCurveUserInfoKey] as! UInt
    let targetFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue

    self.bottomConstraint.constant = UIScreen.main.bounds.height - targetFrame.origin.y

    UIView.animate(withDuration: duration) {
        self.view.layoutIfNeeded()
    }
}