无法调整集合视图高度
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 函数中的单元格高度
我有一个 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 函数中的单元格高度