問題
よくScrollView+TextFieldのような画面で、キーボードが隠れないようにするためにキーボードの開閉の通知を受け取ってscrollInsetをいい感じに調整したりする場合があります
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: .UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: .UIKeyboardWillHide, object: nil)
}
@objc private func keyboardWillShow(_ notification: Notification) {
guard let userInfo = notification.userInfo as? [String: Any] else {
return
}
guard let keyboardInfo = userInfo[UIKeyboardFrameBeginUserInfoKey] as? NSValue else {
return
}
guard let duration = userInfo[UIKeyboardAnimationDurationUserInfoKey] as? Double else {
return
}
let keyboardSize = keyboardInfo.cgRectValue.size
let contentInsets = UIEdgeInsets(top: 0, left: 0, bottom: keyboardSize.height, right: 0) //←
UIView.animate(withDuration: duration, animations: {
self.scrollView.contentInset = contentInsets
self.scrollView.scrollIndicatorInsets = contentInsets
self.view.layoutIfNeeded()
})
}
@objc private func keyboardWillHide(_ notification: Notification) {
scrollView.contentInset = .zero
scrollView.scrollIndicatorInsets = .zero
}
しかし、iOS11だと上記処理のうち、 keyboardSize.height
が0になってしまう問題があるようです。
これにハマって、最初の1回目のキーボード表示では高さが取得できていい感じにinsetが調整されるものの、2回目以降、アプリを再起動するまでずっと0になってて...
修正方法
UIKeyboardFrameBeginUserInfoKey
を UIKeyboardFrameEndUserInfoKey
に変更します。
guard let keyboardInfo = userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue else {
return
}
いままでBeginとEndとあってどっち使うんだって思っていたんですけど、Endの方を使っておけば大丈夫そうです。