Aligning collection view cells to fit exactly 3 per row
You have to implement the
UICollectionViewDelegateFlowLayout
for the spacing stuff.
Set the size of the collectionViewCells like this:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let yourWidth = collectionView.bounds.width/3.0
let yourHeight = yourWidth
return CGSize(width: yourWidth, height: yourHeight)
}
You can also add these functions to get your spacing of the collectionViewCells correct:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets.zero
}
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
}
UICollectionViewCell size for 3 items per row
This looks like you're not taking into account the layout's minimumInteritemSpacing
. The formula to calculate the item's width should be
float cellWidth = (screenWidth - 2.0 * minimumInteritemSpacing) / 3.0;
Fit given number of cells in uicollectionview per row
To better explain the math, faarwa's example is only for 4 cells. Assuming 1 row, there are 5 blocks of spacing for 4 cell items (stick out 4 fingers and count the spaces from far end of pinky to far end of index finger).
There will always be n + 1 spaces for the n cells you have in one row. Faarwa assumes each space is 10 so he multiplied 5 cells by 10 to get 50. You need to figure out how much space you have left to work with after padding— so if assuming your screen width is 200, you must subtract the two values to get the remaining width, or "(collectionView.frame.size.width-50)".
Continuing with the 200 width assumption and 4 cell items, you must divide your difference (150) by 4 to get the width each cell should be for equal spacing.
Experiment and go through some trial and error, but here are the 2 methods I used to get a collection view of exercise sets from an array of set objects.
// UICollectionViewDataSource method
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
let numberOfSets = CGFloat(self.currentExSets.count)
let width = (collectionView.frame.size.width - (numberOfSets * view.frame.size.width / 15))/numberOfSets
let height = collectionView.frame.size.height / 2
return CGSizeMake(width, height);
}
// UICollectionViewDelegateFlowLayout method
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout,
insetForSectionAtIndex section: Int) -> UIEdgeInsets {
let cellWidthPadding = collectionView.frame.size.width / 30
let cellHeightPadding = collectionView.frame.size.height / 4
return UIEdgeInsets(top: cellHeightPadding,left: cellWidthPadding, bottom: cellHeightPadding,right: cellWidthPadding)
}
SCREENSHOT:
two cell items
four cell items
How to display 3 cell per row UICollectionView
Replace this line
let width = (bounds.size.width - leftAndRightPaddings) / numberOfItemsPerRow
with
let width = (bounds.size.width - leftAndRightPaddings*4) / numberOfItemsPerRow
As you are not considering spacing between two items & Right insets
spacing therefore it is not adjusting in the screen.
private let leftAndRightPaddings: CGFloat = 15.0
private let numberOfItemsPerRow: CGFloat = 3.0
let bounds = UIScreen.mainScreen().bounds
let width = (bounds.size.width - leftAndRightPaddings*(numberOfItemsPerRow+1)) / numberOfItemsPerRow
let layout = userDetailCollection.collectionViewLayout as! UICollectionViewFlowLayout
layout.itemSize = CGSizeMake(width, width)
Try this code
How to I get three cells pr row in a UICollectionView. (Works on simulator, but not on phone)
To calculate the itemSize, you simply need to conform your ViewController
to UICollectionViewDelegateFlowLayout
protocol
and implement the below methods,
extension ViewController: UICollectionViewDelegateFlowLayout {
enum Constants {
static let interItemSpacing: CGFloat = 3.0
static let lineSpacing: CGFloat = 3.0
static let itemsPerRow = 3
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = (collectionView.bounds.width - (Constants.interItemSpacing * (CGFloat(Constants.itemsPerRow) - 1))) / CGFloat(Constants.itemsPerRow)
return CGSize(width: width, height: width)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return Constants.interItemSpacing
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return Constants.lineSpacing
}
}
In the above code, I've also created an enum Constants
to define the constant values required in the methods.
Also, specify the scrollDirection
in the storyboard
itself instead of doing it programatically.
UICollectionView display 3 items per row
I know it is so late, but the solution that i am currently using and handled this case was by using KRLCollectionViewGridLayout as below
KRLCollectionViewGridLayout* aFlowLayout = [[KRLCollectionViewGridLayout alloc]init];
aFlowLayout.aspectRatio = 1;
aFlowLayout.sectionInset = UIEdgeInsetsMake(2, 2, 2, 2);
aFlowLayout.interitemSpacing = 2;
aFlowLayout.lineSpacing = 2;
aFlowLayout.numberOfItemsPerLine = 3;
aFlowLayout.scrollDirection = UICollectionViewScrollDirectionVertical;
_collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width,self.view.frame.size.heigh) collectionViewLayout:aFlowLayout];
You can find KRLCollectionViewGridLayout library class using this link
I want the Collection view to show 2 Columns per Row, how do I do that? [with Swift 5 answers please]
You need not check the device size because we can use the collectionView width to calculate the width of the cell. Using the cell width you can calculate the height as per your need.
One more thing: You need to use UICollectionViewDelegateFlowLayout & confirm the delegate & implement method below
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
{
let padding: CGFloat = 25
let collectionViewSize = collectionView.frame.size.width - padding
return CGSize(width: collectionViewSize/2, height: 115)
}
Related Topics
Swift Parse Json - the Data Couldn'T Be Read Because It Isn'T in the Correct Format
Presenting Modal in iOS 13 Fullscreen
What Is the Ibeacon Bluetooth Profile
Ios - Dismiss Keyboard When Touching Outside of Uitextfield
How to Intercept Touches Events on a Mkmapview or Uiwebview Objects
Iphone Keyboard Covers Uitextfield
Rotate Scncamera Node Looking At an Object Around an Imaginary Sphere
Append Data to a Post Nsurlrequest
Ansible Regex_Findall Multiple Strings
How to Safely Delete Contents of Xcode Derived Data Folder
Convert Utf-8 Encoded Nsdata to Nsstring
Objective-C Arc: Strong VS Retain and Weak VS Assign
How to Tell If Uiviewcontroller'S View Is Visible
Undefined Symbols For Architecture I386: _Objc_Class_$_Skpsmtpmessage", Referenced From: Error