Какова скорость анимации клавиатуры, появляющейся в 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()
})
}
Ответы
Ответ 1
Вы можете получить продолжительность анимации и кривую анимации из словаря userInfo на клавиатуреWillShow: уведомления.
Сначала зарегистрируйтесь для получения уведомления
[[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 Version
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil)
@objc func keyboardWillShow(_ notification: Notification) {
let duration = notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey]
let curve = notification.userInfo?[UIResponder.keyboardAnimationCurveUserInfoKey]
}
Ответ 2
Ответ с переменной продолжительностью прав и работа 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 больше не работает, а преобразование более строгое.
Ответ 3
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)
Ответ 4
Обновление 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 duration safely unwraped as a double
}
Наконец, не забудьте удалить наблюдателя в методе deinit
:
deinit {
NotificationCenter.default.removeObserver(self)
}
Ответ 5
Во-первых, выбранный ответ - правильный путь.
Больше может быть предоставлено вот что такое анимация. Если вы напечатаете все CAAnimations в блоке UIViewAnimation, вы обнаружите, что это CASpringAnimation при настройке кривой анимации на тот, который указан в уведомлении клавиатуры. Продолжительность - 0,5, а другие параметры:
let ani = CASpringAnimation(keyPath: someKey)
ani.damping = 500
ani.stiffness = 1000
ani.mass = 3
ani.duration = 0.5
Приведенный выше код может точно воспроизвести анимацию.
Когда анимационная кривая будет установлена на клавиатуру, анимация UIView будет игнорировать длительность параметра. (Если вы действительно хотите изменить продолжительность, отрегулируйте значение mass
.)
Ответ 6
//сначала объявим делегат в вашем классе 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
}
Ответ 7
Я хотел бы указать на то, что помогло мне решить эту проблему. Мне нужен размер клавиатуры из-за нового "быстрого вида" и его способности показывать/скрывать (только для 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
//--------------------------------------------------------------
// 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()
}
Ответ 9
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)
}