Collection view cells are not showing correctly from left to right. It has the gap in center. How can I correct this issue.
collectionView_.register(UINib.init(nibName: String(describing: GoalSelectionCollectionViewCell.self), bundle: nil), forCellWithReuseIdentifier: reuseIdentifier)
collectionView_.allowsMultipleSelection = true
if let flowLayout = collectionView_?.collectionViewLayout as? UICollectionViewFlowLayout {
flowLayout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let itemSize:CGSize = CGSize(width: 80.0, height: 30.0);
return itemSize;
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 20.0;
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 20.0;
}
You need to conform to UICollectionViewDelegateFlowLayout and you also need to set minimumLineSpacing (min spacing between lines) and minimumInteritemSpacing (min spacing in between items in same row)
Related
I have a vertical UICollectionView which contains 5 different types of cells. The 4 of them take the whole width of the UICollectionView, so the func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize gets the work done.
The other 2 are of the same size but their default position needs to be changed; I want them to be aligned from left to right, instead of the centered default.
Here's how I set up my UICollectionView:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
switch typesOfCellsArray[indexPath.row] {
case .createVoiceRoom:
return CGSize(width: collectionView.frame.width, height: 70)
case .voiceRooms:
let height: CGFloat = content.voiceRooms.count > 3 ? 256 : 128
return CGSize(width: collectionView.frame.width, height: height)
case .seeMoreVoiceRooms:
return CGSize(width: collectionView.frame.width, height: 50)
case .newStatus:
let width = collectionView.frame.width / 4
return CGSize(width: width, height: width + 40)
case .status:
let width = collectionView.frame.width / 4
return CGSize(width: width, height: width + 40)
}
}
Here's how they look:
And here's what I want:
I think I need to subclass UICollectionViewLayout to achieve that, but I've failed... Here's what I did:
class HomeCollectionViewLayout: UICollectionViewLayout {
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
guard let collectionView = collectionView else { return nil }
let layoutAttributes = super.layoutAttributesForElements(in: rect)
layoutAttributes?.forEach({ attributes in
if collectionView.cellForItem(at: attributes.indexPath) is NewHomeStatusCollectionViewCell {
let column = attributes.indexPath.row % 3
attributes.frame.origin.x = CGFloat(column-1) * attributes.frame.width
}
})
return layoutAttributes
}
}
Of course, I have set this class as the UICollectionView layout. Any ideas?
You can insert each of you cell into separate section and then control following:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets { }
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat { }
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { }
I tried to make two square collectionView cells in one row. I implemented all of the necessary delegates. When the view is loaded, cells are not square but when I start scrolling, some cells are being square.
when I start scrolling :
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
collectionView.delegate = self
collectionView.dataSource = self
}
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize{
let width = (collectionView.frame.width/2)-0.5
return CGSize(width:width , height: width)
}
Add more margin to width in layout delegate
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize{
let width = (collectionView.frame.width/2)-10
return CGSize(width:width , height: width)
}
I'm struggle a lot. I want to make a menu page with collectionView like this.
I set my width collectionView like this
addSubview(menuCollectionView)
menuCollectionView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
menuCollectionView.leadingAnchor.constraint(equalTo: leadingAnchor),
menuCollectionView.bottomAnchor.constraint(equalTo: bottomAnchor),
menuCollectionView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -129),
menuCollectionView.heightAnchor.constraint(equalToConstant: 33)
])
menuCollectionView.register(MenuCell.self, forCellWithReuseIdentifier: cellID)
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 2
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellID, for: indexPath)
cell.backgroundColor = .red
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: frame.width / 2, height: frame.height)
}
but it end up like this
the cell not fit with the width I setup, and it scroll to down. I was trying to replicate this tutorial from youtube pageMenuVideo but it behave differently. please help me :(
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)
}
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)
}