I am trying to create 2x2 grid layout using collection view.
I have used below code. It's kind of working fine for iPhone 5 but with tweaks. I am trying to write code that can be used on all screen sizes. This is not working on iPhone 6.
public func numberOfSections(in collectionView: UICollectionView) -> Int {
return 2
}
public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 2
}
public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
if let cell1 = cell as? CollectionViewCell {
return cell1
}
return cell
}
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {
let padding: CGFloat = 20
let collectionViewSize = collectionView.frame.size.width - padding
return CGSize(width: collectionViewSize/2, height: collectionViewSize/2+15)
}
public func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
insetForSectionAt section: Int
) -> UIEdgeInsets {
return UIEdgeInsets(
top: 5, left: 5, bottom: 5, right: 5
)
}
public func collectionView(
_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
}
public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 5
}
public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 5
}
I am trying to achieve following layout:
In future this grid can be like 2 columns only and N rows. Each row will always have 2 items.
First of all, get three variables together depending on your needs. Those are the minimum spacing (Both InteritemSpacing and Line spacing - Should be same UXwise but you can change that in delegate methods if you like. The interitem space however must always be equal to minimumSpacing
), edgeInsetPadding and the number of items you want in a row.
private var numberOfItemsInRow = 2
private var minimumSpacing = 5
private var edgeInsetPadding = 10
In your code, you have already defined your Edge Insets as:
UIEdgeInsets(
top: 5, left: 5, bottom: 5, right: 5
)
The left and right insets are important for correctly determining the size of the item. left+right gives us a grand sum of 10. This should be assigned to edgeInsetPadding
like this:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
let inset = UIEdgeInsets(top: 20, left: 20, bottom: 20, right: 20)
edgeInsetPadding = inset.left+inset.right
return inset
}
Now lets get to your UICollectionViewDelegateFlowLayout
. Update the following methods.
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return minimumSpacing
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return minimumSpacing
}
Now lets get to the main part. Modify your sizeForItemAt
in UICollectionViewDelegateFlowLayout
as:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = (Int(UIScreen.main.bounds.size.width) - (numberOfItemsInRow - 1) * minimumSpacing - edgeInsetPadding) / numberOfItemsInRow
return CGSize(width: width, height: width)
}
And this is it. You now get two equal size tiles in 2x2 grid. If you want to change this in future, just change the numberOfItemsInRow
variable to something else. Like 3 for 3x3.
This will be done using the item size of the collectionViewCell
collectionView.delegate = self
extension ViewController : UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let padding = 5
let width = (collectionView.frame.size.width - CGFloat(padding) * 2) / CGFloat(2)
let height = width / 200 * 110 // or what height you want to do
return CGSize(width: width, height: height)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With