Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/108.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios UICollectionViewCell未显示在UICollectionView(Swift3)中_Ios_Uicollectionview_Swift3_Uicollectionviewcell_Uicollectionviewlayout - Fatal编程技术网

Ios UICollectionViewCell未显示在UICollectionView(Swift3)中

Ios UICollectionViewCell未显示在UICollectionView(Swift3)中,ios,uicollectionview,swift3,uicollectionviewcell,uicollectionviewlayout,Ios,Uicollectionview,Swift3,Uicollectionviewcell,Uicollectionviewlayout,我现在搜索了几个小时,在这里和其他任何我能找到的地方阅读了大量的问题,但没有什么能真正解决我的问题 我有一个聊天屏幕作为UICollectionViewController,在那里我从Firebase数据库获取消息。现在我想用消息填充这些单元格,但问题出在这里。细胞没有出现。这是我的viewDidLoad(): 这两个函数应该向我展示细胞: override func collectionView(_ collectionView: UICollectionView, numberOfItems

我现在搜索了几个小时,在这里和其他任何我能找到的地方阅读了大量的问题,但没有什么能真正解决我的问题

我有一个聊天屏幕作为UICollectionViewController,在那里我从Firebase数据库获取消息。现在我想用消息填充这些单元格,但问题出在这里。细胞没有出现。这是我的viewDidLoad():

这两个函数应该向我展示细胞:

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())