キーボードに合わせてUITextFieldやUIViewをアニメーションさせたい時に、animate(withDuration:animations:completion:)
でアニメーションさせようと思ったら上手く動かなかったので調べてみました。
UIResponder
を使うと上手くいったので、困っている人は参考にしてみて下さい!
キーボードの表示・非表示を検知する
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil)
}
// Keybordが表示
@objc dynamic func keyboardWillShow(_ notification: NSNotification){
}
// Keybordが非表示
@objc dynamic func keyboardWillHide(_ notification: NSNotification){
}
キーボードのアニメーションを抽出・アニーメーションを実行
@objc dynamic func keyboardWillShow(_ notification: NSNotification){
// キーボードのdurationを抽出 *1
let durationKey = UIResponder.keyboardAnimationDurationUserInfoKey
let duration = notification.userInfo![durationKey] as! Double
// キーボードのframeを抽出する *2
let frameKey = UIResponder.keyboardFrameEndUserInfoKey
let keyboardFrameValue = notification.userInfo![frameKey] as! NSValue
// アニメーション曲線を抽出する *3
let curveKey = UIResponder.keyboardAnimationCurveUserInfoKey
let curveValue = notification.userInfo![curveKey] as! Int
let curve = UIView.AnimationCurve(rawValue: curveValue)!
let animator = UIViewPropertyAnimator(duration: duration, curve: curve) {
// ここにアニメーション化したいレイアウト変更を記述する
animations?(keyboardFrameValue.cgRectValue)
self.view?.layoutIfNeeded()
}
animator.startAnimation()
}
*1 キーボードのduration
*2 キーボードのframe
*3 アニメーション曲線
レイアウト設定時の注意
textFieldなどをキーボードの上にくっつけて表示したい場合はレイアウトの設定をSafe Area
に合わせるとSafe Area
分の空白はキーボードとViewの間にできてしまうので注意です。
こんな感じでSuper View
に合わせましょう!
これをUIViewControlleなどでextension
して共通で使えるようにするのがおすすめです。