Ios UICollectionViewCell未显示在UICollectionView(Swift3)中
我现在搜索了几个小时,在这里和其他任何我能找到的地方阅读了大量的问题,但没有什么能真正解决我的问题 我有一个聊天屏幕作为UICollectionViewController,在那里我从Firebase数据库获取消息。现在我想用消息填充这些单元格,但问题出在这里。细胞没有出现。这是我的viewDidLoad(): 这两个函数应该向我展示细胞:Ios UICollectionViewCell未显示在UICollectionView(Swift3)中,ios,uicollectionview,swift3,uicollectionviewcell,uicollectionviewlayout,Ios,Uicollectionview,Swift3,Uicollectionviewcell,Uicollectionviewlayout,我现在搜索了几个小时,在这里和其他任何我能找到的地方阅读了大量的问题,但没有什么能真正解决我的问题 我有一个聊天屏幕作为UICollectionViewController,在那里我从Firebase数据库获取消息。现在我想用消息填充这些单元格,但问题出在这里。细胞没有出现。这是我的viewDidLoad(): 这两个函数应该向我展示细胞: override func collectionView(_ collectionView: UICollectionView, numberOfItems
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return messages.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! ChatMessageCell
let message = messages[indexPath.item]
cell.textView.text = message.text
return cell
}
messages[]是从数据库获取消息后附加消息的数组
这没有显示任何细胞。但是如果我实现了一个函数,在该函数中我定义了单元格的布局,并在viewDidLoad()中调用它,那么一切都会按预期显示:
func layoutCells() {
let layout = UICollectionViewFlowLayout()
layout.sectionInset = UIEdgeInsets(top: 0, left: 10, bottom: 10, right: 10)
layout.minimumInteritemSpacing = 5.0
layout.minimumLineSpacing = 5.0
layout.itemSize = CGSize(width: view.frame.width, height: 50)
collectionView!.collectionViewLayout = layout
}
我完全筋疲力尽了,因为我就是不知道该做什么。我的下一步是获取每条消息的高度,以动态更改相应单元格的高度:
func estimatedFrameForText(text: String) -> CGRect {
let size = CGSize(width: 250, height: 1000)
return NSString(string: text).boundingRect(with: size, options: .usesLineFragmentOrigin, attributes: [NSFontAttributeName: UIFont.systemFont(ofSize: 16)], context: nil)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
var height = CGFloat(50)
if let text = messages[indexPath.item].text {
height = estimatedFrameForText(text: text).height
}
return CGSize(width: view.frame.height, height: height)
}
我还在numbersOfItemsInSection设置断点,似乎只有当单元格以特定方式布局时才会执行断点,因为cellForItemAt似乎只有在我调用viewDidLoad()中的LayoutCell()时才会执行,因为如果我不这样做,numbersOfItemsInSection会返回0
非常感谢您的帮助,因为我是Swift3的新手,除了使用消息[indexath.item].text来缩放单元格外,我不知道还能从谁那里获得文本。
谢谢所有提前帮助我的人,因为我已经完成了
编辑:
我的聊天室留言:
import UIKit
class ChatMessageCell: UICollectionViewCell {
let textView: UITextView = {
let tv = UITextView()
tv.font = UIFont.systemFont(ofSize: 16)
tv.translatesAutoresizingMaskIntoConstraints = false
tv.backgroundColor = UIColor.clear
tv.textColor = .white
return tv
}()
let bubbleView: UIView = {
let view = UIView()
view.backgroundColor = UIColor(r: 0, g: 137, b: 249)
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
override init(frame: CGRect) {
super.init(frame: frame)
addSubview(bubbleView)
addSubview(textView)
//constraints
bubbleView.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
bubbleView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
bubbleView.widthAnchor.constraint(equalToConstant: 250).isActive = true
bubbleView.heightAnchor.constraint(equalTo: self.heightAnchor).isActive = true
textView.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
textView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
textView.widthAnchor.constraint(equalToConstant: 250).isActive = true
textView.heightAnchor.constraint(equalTo: self.heightAnchor).isActive = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
函数,在该函数中,我使用从数据库获取的数据填充数组:
var messages = [Message]()
func observeMessages() {
guard let uid = FIRAuth.auth()?.currentUser?.uid else {
return
}
let userMessagesRef = FIRDatabase.database().reference().child("user-messages").child(uid)
userMessagesRef.observe(.childAdded, with: {(snapshot) in
let messageId = snapshot.key
let messagesRef = FIRDatabase.database().reference().child("messages").child(messageId)
messagesRef.observeSingleEvent(of: .value, with: { (snapshot) in
guard let dictionary = snapshot.value as? [String: AnyObject] else {
return
}
let message = Message()
message.setValuesForKeys(dictionary)
if message.chatPartnerId() == self.user?.id {
self.messages.append(message)
DispatchQueue.main.async {
self.collectionView?.reloadData()
}
}
}, withCancel: nil)
}, withCancel: nil)
}
编辑2:
因此,最终解决我问题的方法是简单地添加函数:
func layoutCells() {
let layout = UICollectionViewFlowLayout()
collectionView!.collectionViewLayout = layout
}
并在viewDidLoad()中调用它。我不知道它为什么起作用或者如何起作用,但它起作用了,在一天的寻找解决方案之后,我不愿意再问任何问题:D谢谢大家的帮助
编辑3:
我知道你发现了问题!我通过显示ViewController
func showChatControllerForUser(user: User) {
let chatLogController = ChatLogController(collectionViewLayout: UICollectionViewLayout())
chatLogController.user = user
let chatLogNavigationController = UINavigationController(rootViewController: chatLogController)
present(chatLogNavigationController, animated: true, completion: nil)
}
但它在那一行
let chatLogController = ChatLogController(collectionViewLayout: UICollectionViewFlowLayout())
它应该是collectionViewLayout:UICollectionViewFlowLayout而不是UICollectionViewLayout。这是一个愚蠢的错误,但你知道,现在我不会再这样做了 是否设置了集合视图数据源和委托属性?在viewDidLoad()中设置的是collectionView?.datasource=self和collectionView?.delegate=self,对吗?仅供参考:一切都是以编程方式创建的:)是的,完全正确。你设置了吗?我只是添加了它们,但没有改变。这很奇怪,因为即使我将代码简化为numbersofiteminstation和cellForItemAt函数,并将单元格的背景色设置为蓝色,它也不会显示出来。如果我添加LayoutCells()函数,一切都会正常工作。我把UICollectionView搞砸了吗?因为函数布局中有一个UICollectionViewFlowLayout。您确定正在获取数据吗?您是否
打印了(messages.count)
内numberofitems部分
?数组是否返回任何数据?是否设置了集合视图数据源和委托属性?即collectionView?.datasource=self和collectionView?.delegate=self在viewDidLoad()中是否正确?仅供参考:一切都是以编程方式创建的:)是的,完全正确。你设置了吗?我只是添加了它们,但没有改变。这很奇怪,因为即使我将代码简化为numbersofiteminstation和cellForItemAt函数,并将单元格的背景色设置为蓝色,它也不会显示出来。如果我添加LayoutCells()函数,一切都会正常工作。我把UICollectionView搞砸了吗?因为函数布局中有一个UICollectionViewFlowLayout。您确定正在获取数据吗?您是否打印了(messages.count)
内numberofitems部分
?数组是否返回任何数据?
let chatLogController = ChatLogController(collectionViewLayout: UICollectionViewFlowLayout())