如何防止最后一个表格单元格与键盘重叠

问题描述

我有一个聊天应用程序,可以在表格视图中显示消息。当我调用键盘时,我想:

  1. 滚动到底部的表格视图
  2. 我希望任何消息和键盘之间都没有重叠。
@objc private func keyboardWillShow(notification: NSNotification) {
    if let userInfo = notification.userInfo {
        let keyBoardFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue
        let keyboardViewEndFrame = view.convert(keyBoardFrame!,from: view.window)
        let keyboardHeight = keyboardViewEndFrame.height
        
        tableView.scrollToBottom() { indexPath in
            let rectofCell = self.tableView.rectForRow(at: indexPath)
            let lastCellFrame = self.tableView.convert(rectofCell,from: self.view.window)
            if lastCellFrame.origin.y + lastCellFrame.size.height > keyboardViewEndFrame.origin.y {
                let overlap = lastCellFrame.origin.y + lastCellFrame.size.height - keyboardViewEndFrame.origin.y
                self.tableView.frame.origin.y = -overlap
            }
        }
    }
}

extension UITableView {
    func scrollToBottom(animated: Bool = true,completion: ((IndexPath) -> Void)? = nil) {
        let sections = self.numberOfSections
        let rows = self.numberOfRows(inSection: sections - 1)
        if (rows > 0){
            let indexPath = IndexPath(row: rows - 1,section: sections - 1)
            self.scrollToRow(at: indexPath,at: .bottom,animated: true)
            completion?(indexPath)
        }
    }
}

rectOfCell 的值显示 (0.0,5305.333518981934,375.0,67.33333587646484) 和转换后的值 (0.0,9920.000185648601,67.33333587646484),并且表格视图消失在屏幕之外。

如果最后一条消息与键盘的最终位置重叠,我只想向上移动表格视图。例如,当键盘调用时(当表视图已经在底部或不在底部时),如果键盘的外观没有覆盖消息(即,有只有一条消息)。

解决方法

您不需要为这样的事情管理 tableView.frame。您只需要确保当键盘出现时,tableView 从底部添加必要的 contentInset 值,以便用户仍然可以在键盘仍在屏幕上的情况下看到 tableView 中的所有内容。

你只需要这个 -

// when keyboard appears
let insets = UIEdgeInsets(top: 0,left: 0,bottom: keyboardHeight,right: 0)
tableView.contentInset = insets
tableView.scrollIndicatorInsets = insets

// when keyboard disappears
let insets: UIEdgeInsets = .zero
tableView.contentInset = insets
tableView.scrollIndicatorInsets = insets