我正在使用此代码: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}'
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在视图中加载了这个答案UICollectionView exception in UICollectionViewLayoutAttributes from iOS7,但也无法正常工作。甚至方法collectionViewLayout在reloadData之前和在reloadData之后的invalidateLayout也没有停止崩溃。那么我还能做些什么让它发挥作用?
我从UITableViewCell进入这个CollectionViewController
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
答案 0 :(得分:0)
您没有实施UICollectionViewDataSource
的正确cellForItemAt
方法。这种方法的签名在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
}