UICollectionViewDataSource cellForItemAt don't run at iOS 14 - swift

The cellForItemAt dont't get called after I updated the build target to iOS 14 in Xcode. However, numberOfItemsInSection is getting called but cellForItemAt don't which makes it weird. I have never seen this before.
Any idea of what it could be?
extension LoginTableCell: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.cells.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "LoginCollectionCell",
return cell
}

I can't see anywhere where you set the cell sizes so be sure your cells content sizes are being setup correctly. If you're using a flow layout you can set the size like this:
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .vertical
layout.itemSize = CGSize(width: 50, height: 50)
collectionView.collectionViewLayout = layout
Alternatively you can use the UICollectionViewDelegateFlowLayout protocol to return a size for the cell:
extension LoginTableCell: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.cells.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "LoginCollectionCell",
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 100, height: 100)
}

Related

Xcode Swift UICollectionView: cellForItemAt IndexPath not called but numberOfItemsInSection does

I am currently programming an app with UICollectionView only when I start the app the CollectionView is not displayed. In my app I do not use the StoryBoard but only the ViewController. That's why I inherit from UICollectionViewController in my app. But when I start the app, the UICollectionView is simply not displayed. Through print commands I found out that the numberOfItemsInSection method is called, but the cellForItemAt indexPath is not. I also know that this will probably be a double question, but I still haven't found a solution for 2 hours. CollectionView.delegateand collectionView.dataSource are both set to = self and there are actually no problems with the constrains because I can turn the background of the UICollectionView to black, for example, and everything is displayed correctly there.
I hope someone can help me.
Best regards
// MARK: - Collectionview
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
print("Item wurde erstellt")
return messages.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! ChatMessageCollectionViewCell
let message = messages[indexPath.item]
cell.textView.text = message.message
setUpCell(cell, message)
cell.bubbleViewWidthAnchor?.constant = estimateFrameForText(text: message.message!).width + 32
print("Celle wird erstellt")
return cell
}
I think you have missed the height and width for the cell. You should also check the message array count, perhaps it is zero.
extension YouClass: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return messages.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! ChatMessageCollectionViewCell
let message = messages[indexPath.item]
cell.textView.text = message.message
setUpCell(cell, message)
cell.bubbleViewWidthAnchor?.constant = estimateFrameForText(text: message.message!).width + 32
print("Celle wird erstellt")
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: collBanner.frame.width, height: 140)
}
}

I have CollectionView cells in TableViewCells. I am facing issue in adjusting UIImageView width according to different simluators

I have used CGSize(width: 370, height: 240) in collection view layout function sizeForItemAt which is not dynamic. Width:370 is perfect for iPhone 12/Pro but not for other cases. Hence I'm getting the output below:- iPhone Mini Simulator
My extension in file are:
extension EventAttendTableCell : UICollectionViewDelegateFlowLayout,UICollectionViewDelegate,UICollectionViewDataSource{
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
eventAttendArray.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionViewEventAttend.dequeueReusableCell(withReuseIdentifier: "EventAttendCollectionCell", for: indexPath) as? EventAttendCollectionCell else {fatalError("Error to create TableViewCell")}
let attendData = eventAttendArray[indexPath.row]
cell.imgAttend.image = UIImage(named: attendData.imgEventAttendModel)
cell.lblAttend1.text = attendData.lblEventAttendModelTop
cell.lblAttend2.text = attendData.lblEventAttendModelMiddle
cell.lblAttend3.text = attendData.lblEventAttendModelBottom
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
20
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
20
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 370, height: 240)
}
}
"eventAttendArray" is the Data array from the Model file.

Change vertical cell size space created with a XIB file

How can I change the space between the cells? It currently looks like this:
Nothing that I've tried works, this is my current setup:
and this is where I'm defining the cell:
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
// return products.count
return 3
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
// This determines the size of the cell on the featured slider
return CGSize(width: UIScreen.main.bounds.width, height: 350)
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "FeaturedPostsCollectionViewCell", for: indexPath) as! FeaturedPostsCollectionViewCell
let product = products[indexPath.row]
cell.featuredImage.image = UIImage(named: "4")
cell.lbName.text = product.Name!
cell.lbDesc.text = product.desc!
return cell
}
I've looked around but can't find what is it that is giving it so much space...
I just found the solution, it happened that I had to fix the width to my preferred value:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 310, height: 350)
}

How do you set inner spacing in a collection view cell with 2 cells per row?

Ive been stuck on this for two weeks now. Searched everywhere and still can't find a solution. I want to bring the cells closer to the middle. Also have another collection view with 3 cells per row I need to do the same thing with. Thanks
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 153, height: 241)
}
//
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsetsMake(10, 11, 10, 11)
}
//
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
//
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, maximumLineSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
Jusr read comment , don't forget to setup your cell at let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! UICollectionViewCell
extension ViewController :UICollectionViewDelegate , UICollectionViewDelegateFlowLayout,UICollectionViewDataSource{
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 100 // data source
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! UICollectionViewCell
cell.backgroundColor = .red
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
// 3 cell same size in each row space between them 4
let spaceBetweenCell :CGFloat = 4.0 // if you change this parmters you have to change minimumInteritemSpacingForSectionAt ,
let screenWidth = UIScreen.main.bounds.size.width - CGFloat(2 * spaceBetweenCell)
let totalSpace = spaceBetweenCell * 2.0; // there is 2 between 3 item
return CGSize(width: (screenWidth - totalSpace)/3, height: (screenWidth-totalSpace)/3)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 4.0 // space between sections
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 4.0 // space between items in row
}
}
If you're happy with your cell sizes and just want to move them closer, then adjust your left and right insets (which are the 2nd and 4th inputs to UIEdgeInsetsMake):
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsetsMake(10, 16, 10, 16)
}

UICollectionView cell size - swift 3/4

I am working on Collection view.I want to display 3 rows in collection view . Each row having two cells.The problems is i can't able to fit the cells in a row.Please kindly refer my code which i tried.
import UIKit
class ProductsTableViewCell: UITableViewCell {
#IBOutlet weak var productsCollections: UICollectionView!
override func awakeFromNib() {
super.awakeFromNib()
productsCollections.isScrollEnabled = false
productsCollections.dataSource = self as? UICollectionViewDataSource
productsCollections.delegate = self as? UICollectionViewDelegate
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
extension ProductsTableViewCell: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 6
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Product", for: indexPath)
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: 10, left: 10, bottom: 0, right: 10)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return collectionView.frame.width/9
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return collectionView.frame.width
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let collectionViewWidth = collectionView.bounds.width
let collectionViewHeight = collectionView.bounds.height
return CGSize(width: collectionViewWidth/2.0 , height: collectionViewHeight/2.5)
}
[This is the output i got.][1]}
I want like this.totally 6 rows.Per row 2 cells i want to display
First of all, calculate a row height that you need. So it is depends on screen resolution.
for example :
1- Declare a variable
fileprivate var cellHeight: CGFloat
2- calculate it once in viewDidLoad()
self.cellHeight = yourContainerFrameHeight / 3
3- Remove minimumLineSpacingForSectionAt
4- Calculate cell size.
I'm not sure, but you should not use the size of the CollectionView here (in sizeForItemAt). Instead you can use a fixed UIView or screen sizes. Because we already identify it.
This example has self.contentView you must change with yours or screen size
And try this:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
flowLayout.invalidateLayout()
let vMiddle = self.contentView.frame.size.width / 2.0
//this calculation for prevent next row shifts and fit rows
let cellWidth =
indexPath.row % 2 == 0 ? floor(vMiddle) : self.contentView.frame.size.width - floor(vMiddle)
//print("---------- cell width : \(cellWidth)")
return CGSize(width: cellWidth, height: self.cellHeight)
}