Xcode Swift UICollectionView问题:numberOfItemsInSection已调用但cellForItemAt IndexPath未执行
Hey there, I know how frustrating it is to spend hours stuck on a collection view issue where part of the data source works but cells never get created. Let’s walk through the most likely fixes for your scenario:
1. Confirm messages.count is actually greater than 0
Even though numberOfItemsInSection is being called, if messages.count returns 0, the system has no reason to trigger cellForItemAt. Add a print statement to verify the actual count:
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { print("Actual message count: \(messages.count)") // Add this line to check print("Item wurde erstellt") return messages.count }
If the count is 0, you’ll need to debug why your messages array isn’t being populated correctly before the collection view loads.
2. Validate your collection view layout configuration
Since you’re using a code-only UICollectionViewController, the default flow layout might have invalid item sizes (like width/height set to 0) that prevent cells from being rendered (and thus cellForItemAt from firing). Test with a fixed, visible item size in viewDidLoad:
override func viewDidLoad() { super.viewDidLoad() // Double-check delegate/data source assignments (you mentioned this, but it never hurts to confirm) collectionView.delegate = self collectionView.dataSource = self // Override default flow layout settings guard let flowLayout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout else { print("Collection view isn't using a flow layout!") return } flowLayout.itemSize = CGSize(width: view.bounds.width - 40, height: 60) // Fixed visible size flowLayout.minimumLineSpacing = 8 flowLayout.sectionInset = UIEdgeInsets(top: 16, left: 20, bottom: 16, right: 20) }
If cells start appearing after this, your original dynamic sizing logic was likely causing items to have zero dimensions.
3. Double-check cell registration
Make sure you’ve registered your ChatMessageCollectionViewCell class with the collection view using your cellId in viewDidLoad:
override func viewDidLoad() { super.viewDidLoad() collectionView.register(ChatMessageCollectionViewCell.self, forCellWithReuseIdentifier: cellId) // ... other setup code }
While missing registration usually causes a crash, typos in the reuse identifier string can lead to unexpected behavior—worth ruling out.
4. Verify estimateFrameForText isn’t returning invalid values
Though this shouldn’t prevent cellForItemAt from running, if your estimateFrameForText function returns a width of 0, your cell’s bubble view might collapse. Add a print to confirm it returns a valid value:
func estimateFrameForText(text: String) -> CGRect { let size = CGSize(width: 200, height: .infinity) let options = NSStringDrawingOptions.usesFontLeading.union(.usesLineFragmentOrigin) let rect = text.boundingRect(with: size, options: options, attributes: [.font: UIFont.systemFont(ofSize: 16)], context: nil) print("Estimated text width: \(rect.width)") // Add this to check return rect }
Give these steps a try—more often than not, the issue is either an empty data array or a misconfigured layout that the system interprets as needing no cells to render.
内容的提问来源于stack exchange,提问作者user15816962

