无法调整集合视图高度

Can't ajust uicollectionview height

我有一个 ViewController,里面有一些 header 视图,还有一个 UICollectionView 填充了所有剩余的 space。 (这是一个聊天应用程序)

我没有使用故事板。我的 collection 视图是这样声明的:

self.messagesCollectionView = UICollectionView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height - barHeight), collectionViewLayout: UICollectionViewFlowLayout())
messagesCollectionView.register(MessageCollectionViewCell.self, forCellWithReuseIdentifier: self.cellReuseIdentifier)
messagesCollectionView.delegate = self
messagesCollectionView.dataSource = self
self.view.addSubview(messagesCollectionView)

然后我有这些函数来正确获取我的数据:

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        self.conversation?.messagesList.count ?? 0
    }

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: self.cellReuseIdentifier, for: indexPath) as! MessageCollectionViewCell

    if let message = self.conversation?.messagesList[indexPath.row] {
        cell.createMessage(message: message)
    }

    return cell
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

    if let message = self.conversation?.messagesList[indexPath.row] {
        var heightNeeded = message.text.height(withConstrainedWidth: FDDimensions.shared.k_MessageMaxWidth, font: FDFonts.Montserrat_Regular_14 ?? UIFont.systemFont(ofSize: 14))
        heightNeeded += 22
        heightNeeded += 25

        return CGSize(width: self.view.frame.width, height: heightNeeded)
    } else {
        return CGSize(width: 0, height: 0)
    }
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
    return 10
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
    return UIEdgeInsets.init(top: 10, left: 0, bottom: 10, right: 0)
}

所以这是我得到的一个示例,在调整大小之前具有良好的纵横比:

我想做的是在键盘出现时调整 collection视图高度。

这是我的 func 中的代码,它在键盘出现时被触发:

self.messagesCollectionView.frame.size.height -= keyboardSize.height - (FDUtils.shared.getBottomSafeAreaHeight() ?? 0)
self.messagesCollectionView.reloadData()
self.messagesCollectionView.layoutIfNeeded()

这是我得到的结果:

我所有的细胞都换了,结果彻底坏了

知道我哪里错了吗?我试图只调整 collectionView 的 contentInsets 但我不能使用它,因为如果我使用该解决方案

,滚动条行为将不符合逻辑

谢谢

键盘抬起时添加监听器

NotificationCenter.default.addObserver(self, selector: #selector(showKeyboard), name: UIResponder.keyboardWillShowNotification, object: nil)

@objc func showKeyboard(notification: Notification) {

        collectionView.scrollToItem(at: IndexPath(row: messagesList.count - 1, section: 0), at: .top, animated: false)
}

谢谢

不改变collectionView的高度,而是改变collectionView的contentInset

下面的代码可以帮到你。

@IBOutlet weak var collectionViewBottomConstraint: NSLayoutConstraint!

func addKeyboardNotifications() {
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillhide(notification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillAppear(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
}

@objc func keyboardWillAppear(notification: Notification) {
    if var keyBoardHeight = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as AnyObject?)?.cgRectValue?.size.height {
        if UIScreen.main.bounds.height >= 812.0 {
            keyBoardHeight -= 34.0
        }
        UIView.animate(withDuration: 1.0) {
            //self.collectionViewBottomConstraint.constant = keyBoardHeight
            collectionView.contentInset.bottom = keyBoardHeight
            self.view.layoutIfNeeded()
        }
    }
}

@objc func keyboardWillhide(notification: Notification) {
     collectionView.contentInset = UIEdgeInsets.zero
    UIView.animate(withDuration: 1.0) {
        self.view.layoutIfNeeded()
    }
}

在键盘启动时尝试以下行,因为重新加载不会更改您的单元格框架,因此您需要调用 invalidateLayout() 函数。

self.messagesCollectionView.frame.size.height -= keyboardSize.height - (FDUtils.shared.getBottomSafeAreaHeight() ?? 0)
    self.messagesCollectionView.collectionViewLayout.invalidateLayout()
    self.messagesCollectionView.reloadData()

刚找到答案,感谢帮助过的人

问题出在我的 cellForRowAt 函数中。

我的函数 cell.createMessage 没有调整我的白色单元格的大小以获得良好的消息,我不确定为什么因为我的 sizeForItemAt 函数似乎工作得很好但我设法通过重新计算我的直接在 createMessage 函数中的单元格高度