Swift 3-CollectionView数据源未返回有效单元格 [英] Swift 3 - CollectionView data source did not return a valid cell

查看:170
本文介绍了Swift 3-CollectionView数据源未返回有效单元格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用以下代码: https://www.youtube.com/watch?v= bNtsekO51iQ ,但是当我实现我的数据并使用collectionView.reloadData()时,由于未捕获的异常'NSInternalInconsistencyException'而终止,并以错误代码 ***终止了应用程序,原因:'集合视图的数据源做了不会从-collectionView:cellForItemAtIndexPath:返回有效的单元格以获取索引路径< NSIndexPath:0xc000000000000016>{length = 2,path = 0-0}'

I am using this code: https://www.youtube.com/watch?v=bNtsekO51iQ , but when I implement my data and use collectionView.reloadData() it crashes with error code *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'the collection view's data source did not return a valid cell from -collectionView:cellForItemAtIndexPath: for index path <NSIndexPath: 0xc000000000000016> {length = 2, path = 0 - 0}'

class ChatLogController: UICollectionViewController, UICollectionViewDelegateFlowLayout {

    var userId:Int?
    var position:Int = 0
    var otherAvatar:UIImage = UIImage(named: "defaultAvatar")!
    var otherName:String = ""
    var otherSex:String = ""
    var otherBanned:Int = 0
    var otherBlocked:Int = 0
    var messagesDates:[String] = []
    var messagesText:[String] = []
    var messagesIds:[String] = []
    var messagesPics:[UIImage?] = []
    var messagesSeen:[Int] = []
    var messagesWhoSendIt:[Int] = []
    private let cellId = "cellId"
    override func viewDidLoad() {
        super.viewDidLoad()
        collectionView?.register(ChatLogMessageCell.self, forCellWithReuseIdentifier: cellId)
        collectionView!.isPrefetchingEnabled = false
        loadChatsFor(position: position)
    }    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return messagesIds.count
    }

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath as IndexPath) as! ChatLogMessageCell

        cell.messageTextView.text = messagesText[indexPath.row]


            cell.profileImageView.image = UIImage(named: "defaultAvatar")!

            let size = CGSize(width:250,height:1000)
            let options = NSStringDrawingOptions.usesFontLeading.union(.usesLineFragmentOrigin)
            let estimatedFrame = NSString(string: messagesText[indexPath.row]).boundingRect(with: size, options: options, attributes: [NSFontAttributeName: UIFont.systemFont(ofSize: 18)], context: nil)

        cell.messageTextView.frame = CGRect(x:48 + 8, y:0, width:estimatedFrame.width + 16, height:estimatedFrame.height + 20)

        cell.textBubbleView.frame = CGRect(x:48, y:0, width:estimatedFrame.width + 16 + 8, height:estimatedFrame.height + 20)

        return cell
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
            let size = CGSize(width:250,height:1000)
            let options = NSStringDrawingOptions.usesFontLeading.union(.usesLineFragmentOrigin)
            let estimatedFrame = NSString(string: messagesText[indexPath.row]).boundingRect(with: size, options: options, attributes: [NSFontAttributeName: UIFont.systemFont(ofSize: 18)], context: nil)

        return CGSize(width:view.frame.width, height:estimatedFrame.height + 20)
    }


    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        return UIEdgeInsetsMake(8, 0, 0, 0)
    }

}

class ChatLogMessageCell: BaseCell {

    let messageTextView: UITextView = {
        let textView = UITextView()
        textView.font = UIFont.systemFont(ofSize: 18)
        textView.text = "Sample message"
        textView.backgroundColor = UIColor.clear
        return textView
    }()

    let textBubbleView: UIView = {
        let view = UIView()
        view.backgroundColor = UIColor(white: 0.95, alpha: 1)
        view.layer.cornerRadius = 15
        view.layer.masksToBounds = true
        return view
    }()

    let profileImageView: UIImageView = {
        let imageView = UIImageView()
        imageView.contentMode = .scaleAspectFill
        imageView.layer.cornerRadius = 15
        imageView.layer.masksToBounds = true
        return imageView
    }()

    override func setupViews() {
        super.setupViews()

        addSubview(textBubbleView)
        addSubview(messageTextView)

        addSubview(profileImageView)
        addConstraintsWithFormat(format:"H:|-8-[v0(30)]", views: profileImageView)
        addConstraintsWithFormat(format:"V:[v0(30)]|", views: profileImageView)
        profileImageView.backgroundColor = UIColor.red
    }

}
extension UIView {

    func addConstraintsWithFormat(format: String, views: UIView...) {

        var viewsDictionary = [String: UIView]()
        for (index, view) in views.enumerated() {
            let key = "v\(index)"
            viewsDictionary[key] = view
            view.translatesAutoresizingMaskIntoConstraints = false
        }

        addConstraints(NSLayoutConstraint.constraints(withVisualFormat: format, options: NSLayoutFormatOptions(), metrics: nil, views: viewsDictionary))
    }


}
class BaseCell: UICollectionViewCell {
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupViews()
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    func setupViews() {
    }
}

在loadChatsFor中,我从Web获取数组数据,并使用collectionView.reloadData(),但是当执行此功能时,它会使我的应用程序崩溃.我一直在寻找答案,但是没有成功.我已添加IOS 10函数collectionView!.isPrefetchingEnabled = false,因为确实从此答案中加载了iOS7的UICollectionViewLayoutAttributes中的UICollectionView异常,但也无法正常工作.即使reloadData之前和reloadData之后的方法collectionViewLayout invalidateLayout也无法停止崩溃.那么我还能做些什么来使它工作呢?

In loadChatsFor I get the array data from web and I use collectionView.reloadData(), but when this function is performed it crashes my app. I've searched for answer, but unsuccessfully. I've added IOS 10 function collectionView!.isPrefetchingEnabled = false in view did load from this answer UICollectionView exception in UICollectionViewLayoutAttributes from iOS7, but also not working. Even the method collectionViewLayout invalidateLayout before reloadData and after reloadData doesn't stop the crash. So what else I can do to make it work ?

我要从UITableViewCell进入这个CollectionViewController

I am coming in this CollectionViewController from UITableViewCell

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let layout = UICollectionViewFlowLayout()
    let controller = ChatLogController(collectionViewLayout: layout)
    controller.userId = chatUserIds[indexPath.row]
    navigationController?.pushViewController(controller, animated: true)
}

我已经在tableview的类中添加了UICollectionViewDelegateFlowLayout

I've added UICollectionViewDelegateFlowLayout in the class of the tableview

推荐答案

您没有实现正确的

You are not implementing correct cellForItemAt method of UICollectionViewDataSource. Signature of this method is changed in Swift 3 like this.

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath as IndexPath) as! ChatLogMessageCell

    cell.messageTextView.text = messagesText[indexPath.row]


    cell.profileImageView.image = UIImage(named: "defaultAvatar")!

    let size = CGSize(width:250,height:1000)
    let options = NSStringDrawingOptions.usesFontLeading.union(.usesLineFragmentOrigin)
    let estimatedFrame = NSString(string: messagesText[indexPath.row]).boundingRect(with: size, options: options, attributes: [NSFontAttributeName: UIFont.systemFont(ofSize: 18)], context: nil)

    cell.messageTextView.frame = CGRect(x:48 + 8, y:0, width:estimatedFrame.width + 16, height:estimatedFrame.height + 20)

    cell.textBubbleView.frame = CGRect(x:48, y:0, width:estimatedFrame.width + 16 + 8, height:estimatedFrame.height + 20)

    return cell
}

这篇关于Swift 3-CollectionView数据源未返回有效单元格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆