TextFieldをキーボードに合わせて動かす

TableViewの操作

TableViewのコードでのスクロール

tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .bottom, animated: true)

TableViewの余白設定

以下のようにTableViewに、上下左右に余白を設定できます。これを利用して、入力時に、キーボードでチャットの内容が隠れないようにします。

tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)

キーボードの上にTextFieldを表示する

inputAccessoryViewで表示したいViewを指定して、canBecomeFirstResponderで入力に反応できるようにします。

override var inputAccessoryView: UIView? {
    return bottomInputView
}

override var canBecomeFirstResponder: Bool {
    return true
}

追加したコード


override func viewDidLoad() {
    ...
    tableView.keyboardDismissMode = .interactive
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
    tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 60.0, right: 0)
}

private lazy var bottomInputView: InputView = {
    let view = InputView()
    view.frame = .init(x: 0, y: 0, width: view.frame.width, height: 100)
    view.delegate = self
    return view
}()

func scrollToBottom(){
    let rowNum = tableView.numberOfRows(inSection: 0)
    if rowNum != 0 {
        tableView.scrollToRow(at: IndexPath(row: rowNum-1, section: 0), at: .bottom, animated: true)
    }
}

@objc func keyboardWillShow(_ notification: Notification){
    if let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue {
        let keyboardHeight = keyboardFrame.cgRectValue.height
        tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: keyboardHeight, right: 0)
        scrollToBottom()
    }
}

@objc func keyboardWillHide(){
    tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
}

override var inputAccessoryView: UIView? {
    return bottomInputView
}

override var canBecomeFirstResponder: Bool {
    return true
}

完成したコード

import Foundation
import UIKit

class ChatView :UIViewController,UITableViewDelegate,UITableViewDataSource,InputViewDelegate {
    
    @IBOutlet weak var tableView: UITableView!
    
    private lazy var bottomInputView: InputView = {
        let view = InputView()
        view.frame = .init(x: 0, y: 0, width: view.frame.width, height: 100)
        view.delegate = self
        return view
    }()
    
    var roomData:ChatRoom!
    var chatData:[ChatText] = []
    var database = DatabaseHelper()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        database.getUserName(userID: roomData.userID, result: {
            name in
            self.navigationItem.title = name
        })
        database.chatDataListener(roomID: roomData.roomID, result: {
            result in
                self.chatData = result
                self.messageUpdated()
        })
        tableView.keyboardDismissMode = .interactive
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
        tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 60.0, right: 0)
    }
    
    func messageUpdated(){
        tableView.reloadData()
        scrollToBottom()
    }
    
    @objc func keyboardWillShow(_ notification: Notification){
        if let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue {
            let keyboardHeight = keyboardFrame.cgRectValue.height
            tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: keyboardHeight, right: 0)
            scrollToBottom()
        }
    }
    
    func scrollToBottom(){
        let rowNum = tableView.numberOfRows(inSection: 0)
        if rowNum != 0 {
            tableView.scrollToRow(at: IndexPath(row: rowNum-1, section: 0), at: .bottom, animated: true)
        }
    }
    
    @objc func keyboardWillHide(){
        tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 60, right: 0)
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return chatData.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let data = chatData[indexPath.row]
        let cell:UITableViewCell
        if data.userID == AuthHelper().uid() {
            cell = tableView.dequeueReusableCell(withIdentifier: "cell2")!
        } else {
            cell = tableView.dequeueReusableCell(withIdentifier: "cell1")!
        }
        let imageView = cell.viewWithTag(2) as! UIImageView
        imageView.layer.cornerRadius = imageView.frame.size.height * 0.5
        imageView.clipsToBounds = true
        database.getImage(userID: data.userID, imageView: imageView)
        let label = cell.viewWithTag(1) as! UILabel
        label.text = data.text
        label.layer.cornerRadius = label.frame.size.height * 0.5
        label.clipsToBounds = true
        return cell
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 70.0
    }
    
    override var inputAccessoryView: UIView? {
        return bottomInputView
    }
    
    override var canBecomeFirstResponder: Bool {
        return true
    }
    
}

コメント

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