Swift

【Swift】tableViewでTextFieldがキーボードの下に隠れないように自動でスクロールする

「UITableView」を使っている時に下の方に「TextField」を配置するとキーボードで隠れてしまうので、自動でスクロールして、キーボードの上にTextFieldが来るようにします。

「UITableViewController」を使っている場合には何もしなくても勝手にスクロールしてくれます。

ViewControllerにTableViewとセルを配置する

画面が自動でスクロールされることがわかるように「TextField」を配置したセルをキーボードで隠れるぐらい並べます。(ここでは15個にしました)

cellの「Identifier」は「reuseIdentifier」にします。

コード

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var tableView: UITableView!
    var offset: CGPoint?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.delegate = self
        tableView.dataSource = self
        tableView.tableFooterView = UIView()
        
        NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
    }
    
    @objc func keyboardWillShow(_ notification: NSNotification) {
        offset = tableView.contentOffset
        if let keyboardHeight = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue.height {
            tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: keyboardHeight, right: 0)
        }
    }

    @objc func keyboardWillHide(_ notification: NSNotification) {
        UIView.animate(withDuration: 0.2, animations: {
            if let unwrappedOffset = self.offset {
                self.tableView.contentOffset = unwrappedOffset
            }
            self.tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
        })
    }
}

extension ViewController: UITableViewDelegate, UITableViewDataSource {
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        50
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 15
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)
        return cell
    }
}