【Swift5】scrollViewを使って画面下にあるtextfieldがキーボードで隠れないようにした。

入力フォームなどで縦に長くなった時、下の方のtextFieldがキーボードに隠れて困ることがよくあります。
それを解消しました。
前回の記事のようにscrollViewとstackViewを使っている場合に便利です。

参考サイト
Swift:TextFieldが隠れちゃうのをなんとかする!|プログラミング初心者のプロへの道
UITextFieldを使用する時に必要なあれこれ – Qiita
[Swift4]複数のTextFieldがキーボードに隠れて入力できない時の対策 – あなたにフィット

上記2つのサイトを参考にSwift5で簡単に書いてみます。

まずは前々回の記事を参考にscrollView – stackView – view – textfieldという階層を作ります。
【Swift5】縦長のスクロール画面をscrollViewとstackViewを使って作ると便利だった。改訂版 | iPhoneアプリ備忘録
わかりやすくViewの色を塗り分けておきます。
スクリーンショット 2020-04-10 21.03.20

0vz6x-pfv2f

あと、前回の記事を参考にキーボードを閉じるボタンも付けておきます。
【Swift5】textFieldのキーボードに閉じるボタンを付ける。 | iPhoneアプリ備忘録

このままだとスクロールはしますが一番下の青のtextfieldに入力しようとしても隠れて見えません。
キーボードが出た時にキーボードの高さ分だけスクロールビューを動かします。
以下コード

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var scrollView: UIScrollView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        configureObserver()
    }

    override func viewWillDisappear(_ animated: Bool) {
        removeObserver()
        super.viewWillDisappear(animated)
    }
    
    // MARK: キーボードでスクロール変更
    //キーボードの出現でスクロールビューを変更するのを監視用オブザーバー
    func configureObserver() {
        NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil)
        //ここでUIKeyboardWillShowという名前の通知のイベントをオブザーバー登録をしている
        NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillHide(_:)), name: UIResponder.keyboardDidHideNotification, object: nil)
        //ここでUIKeyboardWillHideという名前の通知のイベントをオブザーバー登録をしている
    }
    
    func removeObserver() {
        NotificationCenter.default.removeObserver(self)
    }

        //UIKeyboardWillShow通知を受けて、実行される関数
    @objc func keyboardWillShow(_ notification: NSNotification){
        guard let userInfo = notification.userInfo else { return }
        let keyboardSize = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue.height
        scrollView.contentInset.bottom = keyboardSize
    }
       
       
       //UIKeyboardWillShow通知を受けて、実行される関数
    @objc func keyboardWillHide(_ notification: NSNotification){
        scrollView.contentInset = .zero
        scrollView.scrollIndicatorInsets = .zero
       }
}

// MARK: - キーボードにと閉じるボタンを付ける
//storybordで該当テキストフィールドを選択し、identity Inspectorでclassを DoneTextFierdに切り替える
class DoneTextFierd: UITextField{

    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        commonInit()
    }

    private func commonInit(){
        let tools = UIToolbar()
        tools.frame = CGRect(x: 0, y: 0, width: frame.width, height: 40)
        let spacer = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil)
        let closeButton = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(self.closeButtonTapped))
        tools.items = [spacer, closeButton]
        self.inputAccessoryView = tools
    }

    @objc func closeButtonTapped(){
        self.endEditing(true)
        self.resignFirstResponder()
    }
}

こんな感じになります。
2hafl-4l5jh

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です