UICollectionView different size cell and item count - swift

Using UICollectionView flow delegate, I'm trying to accomplish this but I still need to remove the huge spacing in the two cell areas.
My Code :
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
if indexPath.row == 0 || indexPath.row == 5 {
return CGSize(width: (getWidth()/2) , height: (getWidth()/2))
}
return CGSize(width: (getWidth()/4) , height: (getWidth()/4))
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
}
Expected :

It is impossible to do this using plain UICollectionViewLayout. By its nature, UICollectionViewLayout is a "line-braking-layout" and line-height is the height of its tallest element. Please see the following:
Apple docs on using UICollectionViewFlowLayout
However, the behavior you want can be achieved by subclassing UICollectionViewFlowLayout. Here is a guide on how to do it:
Creating custom layouts

Related

How to Center Individual Cells to Screen in UICollectionView?

I have two items in my horizontal collection view, and I am trying to make center them, so that with each swipe, a cell is completely center and evenly spaced from the margins. Also only a single cell can be on the screen at once.
Here is what it looks like at the moment. The cells are not event spaced from the sides.
extension HomeVC : UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: collectionView.bounds.size.width - 25, height: 100)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return .init(top: 0, left: 20, bottom: 0, right: 20)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 20
}
}
They should be like this, equally spaced from the margins.
Make minimum spacing for lines and cell == 0
Please refer to this image
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: collectionView.bounds.size.width - 20, height: 100)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return .init(top: 0, left: 10, bottom: 0, right: 10)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 10
}
Also check Paging Enabled. Fits your case.

UICollectionViewCell: How to Center Cells For UICollectonView

I have a 2-item UICollectionView and I want them to move in a way that whenever the user swipes to the next cell the cell is centered and at any given point, only one cell is seen.
How do I go about doing this programmatically? Also, how do I do this so that it remains the same if I were to switch the simulator to a different iPhone?
Set your view controller as collection view's delegate. Implement UICollectionViewDelegateFlowLayout in your view controller and provide sizeForItem as below.
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: collectionView.bounds.size.width, height: cellHeight))
}
Set section insets and line spacing:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return .zero
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 0
}

UICollectionView with 3 columns doesn't produce the desired result

I'm testing this on iPhone XR simulator. I have 3 rows of images and I want them displayed in 3 columns, 2 points distance top, left, right and bottom. This used to work but for some reason it doesn't now.
extension ProfileVC : UICollectionViewDelegateFlowLayout {
override func size(forChildContentContainer container: UIContentContainer, withParentContainerSize parentSize: CGSize) -> CGSize {
return CGSize(width: collectionView.bounds.width / 3, height: collectionView.bounds.width / 3)
}
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, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: 2, left: 2, bottom: 2, right: 2)
}
}
This is my result:
Try implementing sizeForItemAt indexPath method to fix your collection view for a three columns only with item size dynamically based on screen width.
get the screen width or collection view width, then subtract your preferred spaces (8) then divide by 3 (3 columns).
Also, from your storyboard or nib file set minSpacing for lines = 2 and section insets for top = 2 and comment your above methods and implement only this method
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = (collectionView.frame.width - 8) / 3
return CGSize(width: width, height: width)
}

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)
}

UICollectionViewCell spacing to be zero across all device sizes

I'm having trouble setting my UICollectionViewCells to be all the same width and height so that there are no lines/spacing between each cell. Testing on an smaller iPhone like 5S and SE shows no lines between the cells, but larger iPhones such as 6,7 Pluses do - image description below. My view controller adopts UICollectionViewDelegateFlowLayout, and it has a collectionView.
In viewDidLoad, I set the collectionView's delegate to be the view controller.
override func viewDidLoad() {
super.viewDidLoad()
self.viewController.delegate = self
}
I use the following methods to set the cell size and spacing.
let screenWidth:CGFLoat = UIScreen.main.bounds.width
let cellsPerRow:CGFLoat = 4
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let side:Double = Double(self.screenWidth/self.cellsPerRow)
return CGSize(width: side, height: side)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 0.0
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 0.0
}
iPhone 5S, No Lines
iPhone 7 Plus, Lines
Any recommendations or advice to get rid of these line/spacing is greatly appreciated!