美文网首页
聊天室键盘弹出&键盘收回&发送消息后更新对话列表

聊天室键盘弹出&键盘收回&发送消息后更新对话列表

作者: 华子的学习之路 | 来源:发表于2018-01-29 17:57 被阅读8次

    最近一个朋友做了一个类似于聊天室的界面, 但是遇到了发送消息后, 消息列表中并没有显示的问题, 刚开始也以为是数据源没有更新, 列表没有刷新等问题造成的, 但是在解决过程中发现并不是这么简单, 于是直接写了一个demo, 从头实现了一遍, 而本文主要是讲述其中两个事情: 键盘事件, 更新对话列表.

    添加键盘事件通知

    override func viewDidLoad() {
            super.viewDidLoad()
            
            NotificationCenter.default.addObserver(self, selector: #selector(keyBoardWillShow), name: .UIKeyboardWillShow, object: nil)
            NotificationCenter.default.addObserver(self, selector: #selector(keyBoardWillDiss), name: .UIKeyboardWillHide, object: nil)
        }
    

    收到通知, 触发方法:

    注: 通过修改输入框所在的View与底部Safe Area.Bottom的距离实现页面与键盘的布局变化.

    // MARK: - 通知
    extension ChatRoomVC {
        
        @objc func keyBoardWillShow(notification: NSNotification) {
            let keyBoardCGRect = notification.userInfo?["UIKeyboardFrameEndUserInfoKey"] as? CGRect
            let height = keyBoardCGRect?.height ?? 0
            let duration = notification.userInfo?["UIKeyboardAnimationDurationUserInfoKey"] as? CGFloat
            
            UIView.animate(withDuration: TimeInterval(duration ?? 0)) { [weak self] in
                self?.bottomLayoutConstraint.constant = -height
                self?.view.layoutIfNeeded()
            }
            
            tableView.scrollToRow(at: IndexPath(row: dataSourceArray.count - 1, section: 0), at: .bottom, animated: false)
        }
        
        @objc func keyBoardWillDiss(notification: NSNotification) {
    
            let duration = notification.userInfo?["UIKeyboardAnimationDurationUserInfoKey"] as? CGFloat
            UIView.animate(withDuration: TimeInterval(duration ?? 0)) { [weak self] in
                self?.bottomLayoutConstraint.constant = 0
                self?.view.layoutIfNeeded()
            }
            
            tableView.scrollToRow(at: IndexPath(row: dataSourceArray.count - 1, section: 0), at: .bottom, animated: false)
    }
    

    处理消息发送, 更新对话列表

    注: 这里只是简单的直接修改了本地数据集合, 而实际开发中, 需要通过socket连接, 来完成数据的同步工作.

    // MARK: - UITextFieldDelegate
    extension ChatRoomVC: UITextFieldDelegate {
        func textFieldShouldReturn(_ textField: UITextField) -> Bool {
            dataSourceArray.append(textField.text ?? "")
            let indexPath = IndexPath(row: dataSourceArray.count - 1, section: 0)
            tableView.insertRows(at: [indexPath], with: .bottom)
            tableView.scrollToRow(at: indexPath, at: .bottom, animated: true)
            textField.text = nil
            return true
        }
    }
    

    以下是两个注意点: 当滑动列表或者点击了列表时, 需要回收键盘.

    滑动列表时

    // MARK: - UIScrollViewDelegate
    extension ChatRoomVC: UIScrollViewDelegate {
        func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
            textField.endEditing(true)
        }
    }
    

    点击列表, 这里面有一个问题, 就是UIScrollView, UITableView, UICollectionView是不响应touch事件的, 也就是说只是简单的重写touch的方法是没有用的, 方法不会触发, 如果想让其响应touch事件, 需要下面的处理方法:

    //MARK : - 处理UIScrollView类型不响应touch事件的问题
    extension UITableView {
        open override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
            let view = super.hitTest(point, with: event)
            self.viewController()?.view.endEditing(true)
            if view != nil && view!.isKind(of: UITableView.self) {
                return self
            }else {
                return view
            }
        }
    }
    
    // 重写touch触发的方法
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
            textField.endEditing(true)
        }
    

    相关文章

      网友评论

          本文标题:聊天室键盘弹出&键盘收回&发送消息后更新对话列表

          本文链接:https://www.haomeiwen.com/subject/ackfzxtx.html