Я думаю, что лучший подход - это использовать протоколно-ориентированное программирование, если вы используете Swift.
Прежде всего вы должны создать протокол KeyboardCapable
, который дает любому UIViewController, который ему соответствует, возможность регистрировать и отменять регистрацию наблюдателей с клавиатуры:
import Foundation
import UIKit
protocol KeyboardCapable: KeyboardAnimatable {
func keyboardWillShow(notification: NSNotification)
func keyboardWillHide(notification: NSNotification)
}
extension KeyboardCapable where Self: UIViewController {
func registerKeyboardNotifications() {
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name:UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name:UIKeyboardWillHideNotification, object: nil)
}
func unregisterKeyboardNotifications() {
NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: nil)
}
}
Вы заметили постороннее ключевое слово KeyboardAnimatable
в приведенном выше фрагменте кода. Это просто название следующего протокола, который нам нужно создать:
import Foundation
import UIKit
protocol KeyboardAnimatable {
}
extension KeyboardAnimatable where Self: UIViewController {
func performKeyboardShowFullViewAnimation(withKeyboardHeight height: CGFloat, andDuration duration: NSTimeInterval) {
UIView.animateWithDuration(duration, animations: { () -> Void in
self.view.frame = CGRectMake(view.frame.origin.x, -height, view.bounds.width, view.bounds.height)
}, completion: nil)
}
func performKeyboardHideFullViewAnimation(withDuration duration: NSTimeInterval) {
UIView.animateWithDuration(duration, animations: { () -> Void in
self.view.frame = CGRectMake(view.frame.origin.x, 0.0, view.bounds.width, view.bounds.height)
}, completion: nil)
}
}
Этот протокол KeyboardAnimatable
предоставляет всем UIViewController, соответствующим ему два метода, которые будут анимировать весь вид вверх и вниз соответственно.
Хорошо, поэтому, если KeyboardCapable
соответствует KeyboardAnimatable
, все UIViewController, соответствующие KeyboardCapable
, также соответствуют KeyboardAnimatable
. Это круто.
Давайте посмотрим, как UIViewController
соответствует KeyboardCapable
и реагирует на события клавиатуры:
import Foundation
import UIKit
class TransferConfirmViewController: UIViewController, KeyboardCapable {
//MARK: - LIFE CYCLE
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
registerKeyboardNotifications()
}
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
unregisterKeyboardNotifications()
}
//MARK: - NOTIFICATIONS
//MARK: Keyboard
func keyboardWillShow(notification: NSNotification) {
let keyboardHeight = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).CGRectValue().height
let animationDuration = notification.userInfo![UIKeyboardAnimationDurationUserInfoKey] as! Double
performKeyboardShowFullViewAnimation(withKeyboardHeight: keyboardHeight, andDuration: animationDuration)
}
func keyboardWillHide(notification: NSNotification) {
let animationDuration = notification.userInfo![UIKeyboardAnimationDurationUserInfoKey] as! Double
performKeyboardHideFullViewAnimation(withDuration: animationDuration)
}
}
Теперь ваш UIViewController
будет реагировать на события клавиатуры и, как следствие, анимироваться.
Примечание. Если вы хотите использовать пользовательскую анимацию вместо просмотра или вытягивания изображения, вы должны определить пользовательские методы в протоколе KeyboardAnimatable
или выполнять их в функциях KeyboardCapable
. Это зависит от вас.