2017-02-09 11 views
0

Я использую этот код: https://www.youtube.com/watch?v=bNtsekO51iQ, но когда я реализую свои данные и использовать collectionView.reloadData() он падает с кодом ошибки *** 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}'Swift 3 - источник данных CollectionView не возвращает действительную ячейку

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 Я получаю данные массива из Интернета, и я использую collectionView.reloadData(), но когда эта функция выполняется, это приводит к сбою моего приложения. Я искал ответ, но безуспешно. Я добавил функцию IOS 10 collectionView! .isPrefetchingEnabled = false в поле зрения загрузился из этого ответа UICollectionView exception in UICollectionViewLayoutAttributes from iOS7, но также не работает. Даже метод collectionViewLayout invalidateLayout перед reloadData и после reloadData не останавливает сбой. Так что еще я могу сделать, чтобы он работал?

гряда в этом CollectionViewController от 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) 
} 

Я добавил UICollectionViewDelegateFlowLayout в классе Tableview

ответ

0

Вы не реализуете правильный cellForItemAt метода UICollectionViewDataSource. Подпись этого метода в Swift 3 изменяется следующим образом.

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 
} 
+0

Я нажал перейти на Swift 3, но это, вероятно, ошибка в XCode 8,1 Большое спасибо :) –

 Смежные вопросы

  • Нет связанных вопросов^_^