Swiftでキーボード表示に追随するUITextView

calendar

スポンサーリンク

キーボード表示に追随する入力フィールドの作成

LineのメッセージUIのようにキーボード表示に追随して入力フィールドが下からせり上がる動作をします。

import UIKit

class SampleViewController: UIViewController, UITextViewDelegate {
    
    let inputBackView = UIView()
    let inputTextView = UITextView()
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // TextViewのバックViewの配置
        inputBackView.frame = CGRect(x: 0, y: UIScreen.main.bounds.size.height-50, width: UIScreen.main.bounds.size.width, height: 50)
        inputBackView.backgroundColor = UIColor(red: 0.13, green: 0.61, blue: 0.93, alpha: 1.0)
        self.view.addSubview(inputBackView)
        // UITextViewの配置
        inputTextView.frame = CGRect(x: 10, y: 10, width: UIScreen.main.bounds.size.width-20, height: 30)
        inputBackView.addSubview(inputTextView)
        // UITextViewDelegateの設定
        inputTextView.delegate = self
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        // Viewの表示時にキーボード表示・非表示を監視するObserverを登録する
        let notification = NotificationCenter.default
        notification.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil)
        notification.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil)
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        // Viewの終了時にキーボード表示・非表示時を監視していたObserverを解放する
        let notification = NotificationCenter.default
        notification.removeObserver(self)
        notification.removeObserver(self, name: UIResponder.keyboardWillShowNotification, object: nil)
        notification.removeObserver(self, name: UIResponder.keyboardWillHideNotification, object: nil)
    }
    
    func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
        // returnキーが押された時の動作
        if(text == "\n") {
            textView.resignFirstResponder()
            return false
        }
        return true
    }
    
    @objc func keyboardWillShow(_ notification: Notification) {
        // キーボード表示時の動作をここに記述する
        guard let userInfo = notification.userInfo as? [String: Any] else {
            return
        }
        guard let keyboardInfo = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else {
            return
        }
        guard let duration:TimeInterval = userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double else {
            return
        }
        let keyboardRect:CGRect = keyboardInfo.cgRectValue
        UIView.animate(withDuration: duration, animations: {
            self.inputBackView.frame.origin.y = keyboardRect.origin.y - self.inputBackView.frame.size.height
        },completion:{(finished:Bool) in
            self.inputBackView.frame.origin.y = keyboardRect.origin.y - self.inputBackView.frame.size.height
        })
    }
    
    @objc func keyboardWillHide(_ notification: Notification) {
        // キーボード非表示時の動作をここに記述する
        guard let userInfo = notification.userInfo as? [String: Any] else {
            return
        }
        guard let keyboardInfo = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else {
            return
        }
        guard let duration:TimeInterval = userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double else {
            return
        }
        let keyboardRect:CGRect = keyboardInfo.cgRectValue
        UIView.animate(withDuration: duration, animations: {
            self.inputBackView.frame.origin.y = keyboardRect.origin.y - self.inputBackView.frame.size.height
        },completion:{(finished:Bool) in
            self.inputBackView.frame.origin.y = UIScreen.main.bounds.size.height - self.inputBackView.frame.size.height
        })
    }

}

iOSシミュレーターのキーボードが表示されない場合

動作環境:Xcode10.0, Swift4.2

この記事をシェアする

コメント

コメントはありません。

down コメントを残す