【完全版】キーボードとTextViewが被らない!!動的にLayoutを変更するやり方!!

TextViewを画面いっぱいに広げたものの、キーボード入力した時に被って見えなくなることありますよね。

私もメモアプリを作成していて苦労したので、超ざっくり手順を残します。


まずは完成形を…

 

どこがTextViewかわかりやすいように、背景は灰色にしています。


完成形コード

import UIKit

class MemoViewController: UIViewController,UITextViewDelegate {
    
    @IBOutlet weak var textView: UITextView!
    let BottomHeight:CGFloat = 30
    // TextViewのBottomAnchor
    @IBOutlet weak var textViewBottomConstraint: NSLayoutConstraint!    
    override func viewDidLoad() {
        super.viewDidLoad()
        textView.delegate = self
        // 背景をタップしたらdismissKeyboardメソッドを呼ぶように設定する
        let tapGesture: UITapGestureRecognizer = UITapGestureRecognizer(target:self, action:#selector(dismissKeyboard))
        self.view.addGestureRecognizer(tapGesture)
        
        // キーボードの表示イベントを設定
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
        
    }
    // キーボードを閉じる時に呼ばれる
    @objc func keyboardWillHide() {
        // テキストビューのBottomAnchor制約にBottomHeight(=30)を設定
        textViewBottomConstraint.constant = BottomHeight
        self.view.layoutIfNeeded()
    }
    
    // キーボードを開く時に呼ばれる
    @objc func keyboardWillShow(notification: NSNotification) {
        // キーボードサイズを取得
        if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
        // テキストビューのBottomAnchor制約にキーボードの高さを設定
            textViewBottomConstraint.constant = keyboardSize.height
            self.view.layoutIfNeeded()
        }
    }
    
    @objc func commitButtonTapped() {
        self.view.endEditing(true)
    }
    
    @objc func dismissKeyboard(){
        // キーボードを閉じる
        view.endEditing(true)
    }    

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
        NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillHideNotification, object: nil)
    }

}

 

上記コードをはっつけるだけではダメです。

まずは、StroyBoard上からTextViewに制約をつけましょう!

 

 

 

それが終わったらStroryBoardから

TextViewのBottomAnchorをコードに紐付けをしましょう。

※変数名はtextViewBottomConstraintとしてます。

 

これで動くはずでーす。

コメント

タイトルとURLをコピーしました