Swiftでキーボードの高さだけUITableViewの高さを短くする


iOSでキーボードが表示するときに
そのまま出すとUITableviewの上に被さって表示される

そのため、キーボードが出ている間はUiTableViewの一番下の位置を
safeareaのボトムでなく
キーボードの上にしたいと思い
やり方を調べてみた


#selectorはobjective-cのメソッドを設定しなければならないので
@objcをつけてメソッドを定義する必要がある
コードはこんな感じ

@IBOutlet weak var tableViewBottomConstraint: NSLayoutConstraint!

override func viewWillAppear(_ animated: Bool) {
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name:UIResponder.keyboardWillShowNotification, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name:UIResponder.keyboardWillHideNotification, object: nil)
}

//MARK: KeyBoard
@objc func keyboardWillShow(notification: NSNotification) {
    let userInfo = notification.userInfo!
    let rect = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue
    guard let keyboardHeight = rect?.size.height else {
        return
    }
    let tabBarHeight = self.tabBarController?.tabBar.frame.size.height ?? 0
    
    adViewBottomConstraint.constant = -(keyboardHeight - tabBarHeight)
}

@objc func keyboardWillHide(notification: NSNotification) {
    tableViewBottomConstraint?.constant = 0
}

キーボードの高さはコールバックでしか取れないのでコールバックで取る
userinfoの中に情報入っている
NSValueは、CGRect等のNSObjectを継承してないものをラップしたもの

keyboardFrameBeginUserInfoKeyと書かれているサイトが多いが
正しくはkeyboardFrameEndUserInfoKeyにする必要がある
keyboardFrameBeginUserInfoKeyだと初回のリクエスト時に0が返ってくので注意

最後の注意はkeyboardFrameEndUserInfoKeyはtabBarの高さが入った高さが取れるので
tabBarの高さを引くことでキーボードの高さになる

そして取得したキーボードの高さをtableviewのボトムの制約から引く
キーボードが隠れた時は制約に0を入れる
これでキーボードが出ている時はtableviewのボトムはキーボードの上に
キーボードが隠れている時はtableivewのボトムはsafeareaのボトムになりましたとさ

 

参考
https://stackoverflow.com/questions/26689232/scrollview-and-keyboard-swift
https://qiita.com/sgr-ksmt/items/1d72d9973bc6220a5633
https://stackoverflow.com/questions/28264546/uikeyboardframeenduserinfokey-height-incorrect-should-be-48pt-less/34549428

関連記事:

Pocket