首页 文章

当inputAccessoryView出现时,移动集合视图聊天

提问于
浏览
0

我正在使用聊天屏幕,其中我有 InputAccessoryView 用户类型消息和 UICollectionView 其中包含聊天 . 我想在用户在UICollectionView中发送时显示最新的聊天消息 . 问题是当用户类型消息InputAccessoryView出现在键盘上并且UICollectionView落后于键盘时,所以最新消息不可见 . 我想在键盘出现时将UICollectionView移动到键盘高度 .

我正在使用以下代码 .

这将注册键盘隐藏和显示事件的观察者 .

func handleKeyBoard(){
        NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
    }


@objc func keyboardWillShow(notification: NSNotification) {
        if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
            var contentInset = self.collectionView?.contentInset
            contentInset?.bottom = keyboardSize.height
            self.collectionView?.contentInset = contentInset!
            if self.messages.count > 0{
                UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: {
                    self.view.layoutIfNeeded()

                }, completion: { (completed:Bool) in
                    let indexPath = IndexPath(item: self.messages.count - 1, section: 0)
                    self.collectionView?.scrollToItem(at: indexPath, at: .bottom, animated: true)
                })

            }
        }
    }

在键盘出现的上述功能中我得到它's height which always comes as 50 I don'知道为什么可能是因为 InputAccessoryView . 获得键盘高度后,我为 InputAccessoryView 添加了50多个高度然后更改 UICollectionViewControllercontentInset ,并且在动画完成时我滚动到最后一条消息,它将UICollectionViewController滚动到它的最后一条消息 .

但它没有发生 .

对于UICollectionView,这是我的默认 contentInset .

UIEdgeInsets(top: 8, left: 0, bottom: 52, right: 0)

var contentInset = self.collectionView?.contentInset
                contentInset?.bottom = keyboardSize.height
                self.collectionView?.contentInset = contentInset!

contentInset成为了这个 .

UIEdgeInsets(top: 8, left: 0, bottom: 52, right: 0)

一旦键盘隐藏,下面将设置defaul Inset for collectionview

@objc func keyboardWillHide(notification: NSNotification) {
            if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
              self.collectionView?.contentInset = UIEdgeInsets(top: 8, left: 0, bottom: 52, right: 0)

                UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: {
                    self.view.layoutIfNeeded()

                }, completion: { (completed:Bool) in

                })
            }
        }

任何人都可以帮我找到正确的方法来做到这一点 . 这将非常有帮助 . 几乎所有聊天应用都有此功能,当他们键入时,可以在聊天视图中看到新消息 .

谢谢 .

3 回答

  • 0

    最好的方法是向collectionView和InputAccessoryView添加约束,以便将collectionview的bottomview附加到附件视图和附件视图到超级视图的底部 .
    enter image description here

    enter image description here

    下一步使底部空间的出口限制在.m文件中,并调用scrollViewBottomSpace并添加以下代码 . Constrain将为您完成工作 .

    #pragma mark - 键盘通知

    - (void)addObservers
    {
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
    }
    
    - (void)removeObservers
    {
        [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
        [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
    }
    
    #pragma mark - Keyboard notification handlers
    
    - (void)keyboardWillShow:(NSNotification *)notification
    {
        if(_keyboardIsVisible) return;
    
        CGFloat height = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue].size.height;
    
        [UIView animateWithDuration:0.2 animations:^{
            scrollViewBottomSpace.constant = height+40;
        } completion:^(BOOL finished) {
    
        }];
    
        _keyboardIsVisible = YES;
    }
    
    - (void)keyboardWillHide:(NSNotification *)notification
    {
        if(!_keyboardIsVisible) return;
    
        [UIView animateWithDuration:0.2 animations:^{
            scrollViewBottomSpace.constant = 0;
        } completion:^(BOOL finished) {
    
        }];
    
        _keyboardIsVisible = NO;
    }
    
  • 0

    这很简单,如果你正在使用 UICollectionViewController 你不需要自己管理 contentInset 只需让 CollectionViewController 自己处理它,你只需要在'textView'或'textField'成为第一响应者或你的时候向下滚动发送消息

    要向下滚动 collectionView ,只需使用此功能即可

    func scrollToBottom() {
        let numberOfSections = self.collectionView!.numberOfSections
        if numberOfSections > 0 {
            let numberOfRows = self.collectionView!.numberOfItems(inSection: numberOfSections - 1)
            if numberOfRows > 0 {
                let indexPath = IndexPath(row: numberOfRows-1, section: (numberOfSections-1))
                self.collectionView!.scrollToItem(at: indexPath, at: .bottom, animated: true)
            }
        }
    }
    
  • 0

    在这thread我回答了这个问题,问题是 UIKeyboardFrameBeginUserInfoKey 而不是我用的 UIKeyboardFrameEndUserInfoKey

相关问题