How to Set Uicollectionviewcell Width and Height Programmatically

How to set UICollectionViewCell Width and Height programmatically

Use this method to set custom cell height width.

Make sure to add this protocols

UICollectionViewDelegate

UICollectionViewDataSource

UICollectionViewDelegateFlowLayout

If you are using swift 5 or xcode 11 and later you need to set Estimate Size to none using storyboard in order to make it work properly. If you will not set that than below code will not work as expected.

Sample Image

Swift 4 or Later

extension YourViewController: UICollectionViewDelegate {
//Write Delegate Code Here
}

extension YourViewController: UICollectionViewDataSource {
//Write DataSource Code Here
}

extension YourViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: screenWidth, height: screenWidth)
}
}

Objective-C

@interface YourViewController : UIViewController<UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout>

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return CGSizeMake(CGRectGetWidth(collectionView.frame), (CGRectGetHeight(collectionView.frame)));
}

How to change UICollectionViewCell size programmatically in Swift?

Make sure you conform to UICollectionViewDelegateFlowLayout for your class
(for swift4)

eg. class MyClass: UICollectionViewDelegateFlowLayout

Prior to Swift 3

//Use for size
func collectionView(collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {

}
//Use for interspacing
func collectionView(collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
minimumInteritemSpacingForSectionAtIndex section: Int) -> CGFloat {
return 1.0
}

func collectionView(collectionView: UICollectionView, layout
collectionViewLayout: UICollectionViewLayout,
minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat {
return 1.0
}

// For swift 3

func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {

}

func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 1.0
}

func collectionView(_ collectionView: UICollectionView, layout
collectionViewLayout: UICollectionViewLayout,
minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 1.0
}

// For swift 4

extension MyClass: UICollectionViewDelegateFlowLayout { 
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {

}

func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 1.0
}

func collectionView(_ collectionView: UICollectionView, layout
collectionViewLayout: UICollectionViewLayout,
minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 1.0
}
}

use the same code as shown above for swift 3 but just make sure
your class conforms to protocol UICollectionViewDelegateFlowLayout

How to setup a UICollectionView with dynamic height and dynamic cell widths programmatically?

Here you'll need to create a custom collectionViewLayout by creating a new class that is extending UICollectionViewFlowLayout and in that class you'll need to override the layoutAttributesForElements(in rect: CGRect) method.
In that overridden method, what you'll be doing is basically that you'll be calculating the position for each cell again by modifying the UICollectionViewLayoutAttributes of each cell, and then returning that new modified UICollectionViewLayoutAttributes for each cell.

class LeftAlignedCellsCustomFlowLayout:UICollectionViewFlowLayout {

override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {

//get an array of UICollectionViewLayoutAttributes for all the cells
let attributes = super.layoutAttributesForElements(in: rect)

var leftMargin = sectionInset.left

var maxY: CGFloat = 2.0

let horizontalSpacing:CGFloat = 5

//Modify the UICollectionViewLayoutAttributes for each cell
attributes?.forEach { layoutAttribute in

if layoutAttribute.frame.origin.y >= maxY
|| layoutAttribute.frame.origin.x == sectionInset.left {

leftMargin = sectionInset.left
}

if layoutAttribute.frame.origin.x == sectionInset.left {
leftMargin = sectionInset.left
}else {
layoutAttribute.frame.origin.x = leftMargin
}

leftMargin += layoutAttribute.frame.width + horizontalSpacing

maxY = max(layoutAttribute.frame.maxY, maxY)
}
//return the array of modified UICollectionViewLayoutAttributes
return attributes
}
}

Then in your View where you want to put this custom aligned CollectionView do the following:

  //Let's say you have an IBOutlet of your collectionView as a class-level instance
@IBOutlet weak var leftAlignedCollectionView: UICollectionView!

//put the following code in the awakeFromNib of your View:
let layout = LeftAlignedCellsCustomFlowLayout()
layout.estimatedItemSize = CGSize(width: 1, height: 1)
layout.minimumLineSpacing = 5
layout.minimumInteritemSpacing = 5
leftAlignedCollectionView.collectionViewLayout = layout

Now, all you have to do is make a collectionViewCell which has a label inside it having left,right, top, bottom spacing. And, Inside the cell class put the following code:

var isHeightCalculated: Bool = false

override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {

//We need to cache our calculation to prevent a crash.

if !isHeightCalculated {

layoutIfNeeded()
let size = contentView.systemLayoutSizeFitting(layoutAttributes.size)
var newFrame = layoutAttributes.frame
newFrame.size.width = CGFloat(ceilf(Float(size.width)))
layoutAttributes.frame = newFrame
isHeightCalculated = true

}
return layoutAttributes
}

The overriding of the above method Gives the cell a chance to modify the attributes provided by the layout object.

How to give width and height programatically for collection view cell in ios, swift 3

Method collectionView(_:layout:sizeForItemAt:) is UICollectionViewDelegateFlowLayout protocol's method, so setting delegate and datasource of collectionView is not enough, you need to implement UICollectionViewDelegateFlowLayout with your custom class where you have added collectionView to call UICollectionViewDelegateFlowLayout protocol's methods. So implement UICollectionViewDelegateFlowLayout like below example:

class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {

collection view cell Hight and width in swift

Just implement some UICollectionViewDelegateFlowLayout methods to get the correct size and spacing of the UICollectionViewCells.

Example:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
{
let cellSize = CGSize(width: (collectionView.bounds.width - (3 * 10))/2, height: 120)
return cellSize
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat
{
return 10
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets
{
let sectionInset = UIEdgeInsetsMake(10, 10, 10, 10)
return sectionInset
}

Just change the size and spacing values according to your requirement.

How to set UICollectionViewCell height to 90% of the View (Screen) height?

You can set your UICollectionView's flow layout tile size programmatically. There are a couple of different places you could cause this, I would start with viewWillAppear (in your ViewController class) for starters:

override func viewWillAppear() {
super.viewWillAppear()
if let layout = self.schedulesView.collectionViewLayout as? UICollectionViewFlowLayout {
var cellSize = UIScreen.main.bounds.size // start with the full screen size
cellSize.height *= 0.9 // adjust the height by 90%
layout.itemSize = cellSize // set the layouts item size
}
}


Related Topics



Leave a reply



Submit