当inputAccessoryView出现时,移动收藏夹视图聊天

时间:2018-07-13 06:19:38

标签: ios swift uicollectionview chat inputaccessoryview

我正在使用聊天屏幕,其中有一个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)
                })

            }
        }
    }

在上面的功能中,当键盘出现时,我得到的高度总是50,我不知道为什么可能是由于InputAccessoryView引起的。 获得键盘高度后,我将InputAccessoryView的高度再增加50,然后更改contentInset的{​​{1}},并在动画完成时滚动到最后一条消息,该消息将滚动UICollectionViewController是它的最后一条消息。

但这没有发生。

这是我的默认UICollectionView UICollectionViewController

contentInset

之后

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

contentInset变成这个。

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

以下操作将在键盘隐藏后为集合视图设置默认插入

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

谁能帮助我找到正确的方法来做到这一点。那将非常有帮助。 几乎所有聊天应用都具有此功能,当他们键入内容时,便可以在该聊天视图中看到新消息。

谢谢。

3 个答案:

答案 0 :(得分:0)

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

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

#pragma标记-键盘通知

- (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;
}

答案 1 :(得分: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)
        }
    }
}

答案 2 :(得分:0)

在此thread,我已经回答了这个问题,问题出在UIKeyboardFrameBeginUserInfoKey,而不是我使用的UIKeyboardFrameEndUserInfoKey