Chris Mikkelsen
Chris Mikkelsen

Reputation: 4067

How to resize the collection view cells according to device screen size?

I noticed that the cells would always follow the definition in size inspector. Even if I have already applied UICollectionViewDelegateFlowLayout.

enter image description here

enter image description here

So that's how it looks. But I want the cells to rather look like how it was on a smaller iphone screen.

enter image description here

Upvotes: 33

Views: 51735

Answers (9)

SafoineMoncefAmine
SafoineMoncefAmine

Reputation: 165

in Swift 5

You can just extend your view controller from UICollectionViewDelegateFlowLayout and implement this method:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let height = collectionView.frame.height
        let width  = collectionView.frame.width
        return CGSize(width: width, height: height)
}

in this example I make the width of cells equal to the width of the CollectionView you can adapt it depends on your need.

Upvotes: 4

WaliD
WaliD

Reputation: 239

Adding to Βασίλης Δ's answer make sure to set the estimate size to none under your collection view size inspector. image of Estimate Size in size inspector

Upvotes: -1

CodeChanger
CodeChanger

Reputation: 8371

As per my experience, you have to use UICollectionView methods to get device-specific collection view cell size as per the below methods you can get dynamic width & height of collection view cell.

// Dynamic width & height
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
    float cellSize = collectionView.frame.size.width/values.count;
    return CGSizeMake(cellSize - 10, collectionView.frame.size.height);
}

//For top/bottom/left/right padding method
- (UIEdgeInsets)collectionView:(UICollectionView*)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
{
    return UIEdgeInsetsMake(0, 0, 0, 1);
}



- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
    float width = collectionView.frame.size.width;
    float spacing = [self collectionView:collectionView layout:collectionViewLayout minimumInteritemSpacingForSectionAtIndex:section];
    int numberOfCells = (width + spacing) / (cellSize + spacing);
    int inset = (width + spacing - numberOfCells * (cellSize + spacing) ) / 2;
    
    return UIEdgeInsetsMake(0, inset, 0, inset);
}
- (CGFloat)collectionView:(UICollectionView *) collectionView layout:(UICollectionViewLayout *)collectionViewLayout
minimumInteritemSpacingForSectionAtIndex:(NSInteger) section
{
    return 1.0;
}

Hope this will help you to design your cell-based on device size.

Upvotes: 2

Vasilis D.
Vasilis D.

Reputation: 1456

Swift 4

Multiply the collectionView's frame width/height in an implementation of the sizeForItemAt method.

class yourClassName: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {


    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
            return CGSize(width: self.myCollectionView.frame.height / 6 * 5, height: self.myCollectionView.frame.height / 6 * 5)

        }


}

self.myCollectionView is the reference from you collection view Item
it's important to implement UICollectionViewDelegateFlowLayout

And because it will not fit another cell you will have only one row.

Upvotes: 17

Karanveer Singh
Karanveer Singh

Reputation: 1031

Some of you might need to do this too: In the Storyboard, go to the collectionviewFlowLayout (yellow cube) inside the Collection View, then go to the Size Inspector, make sure the "Estimated Size" is set to "None".

Upvotes: 6

Marat Ibragimov
Marat Ibragimov

Reputation: 1084

Implement sizeForItemAt method according to the view's frame size

Swift

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

    let height = view.frame.size.height
    let width = view.frame.size.width
    // in case you you want the cell to be 40% of your controllers view
    return CGSize(width: width * 0.4, height: height * 0.4)
}

Objective C

- (CGSize)collectionView:(UICollectionView *)collectionView 
              layout:(UICollectionViewLayout *)collectionViewLayout 
   sizeForItemAtIndexPath:(NSIndexPath *)indexPath {

   CGFloat height = self.view.frame.size.height;
   CGFloat width  = self.view.frame.size.width;
   // in case you you want the cell to be 40% of your controllers view
   return CGSizeMake(width * 0.4, height * 0.4);
 }

Upvotes: 59

jignesh Vadadoriya
jignesh Vadadoriya

Reputation: 3310

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

    let theWidth = (_screenSize.width - (15*3))/2    // it will generate 2 column 
    let theHeight = (_screenSize.height - (10*2))/3   // it will generate 3 Row 
    return CGSize(width: theWidth ,height: theHeight)
}

Upvotes: -1

Rohit Parsana
Rohit Parsana

Reputation: 166

In swift 3, You can resize collection view cell as per the screen using collectionViewLayout property.

I.e.

   let numberOfCell = 3
   let cellSpecing = 10
   if let layout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
        layout.itemSize = CGSize(width: (screenSize.width - (cellSpecing * (numberOfCell + 1))) / numberOfCell, height: cellHeight)
        layout.invalidateLayout()
    }

Upvotes: 5

Daniel Dramond
Daniel Dramond

Reputation: 1598

You should try using a simple equation when setting your cell size instead of number like so:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: view.frame.width / 2, height: 350)
    }

dividing it by 2 will mean that the cell always be half of the screens size, taking away and kind of minimumLineSpacing functions and/or and UIEdgeInset methods you have called. Hope this helps.

Upvotes: 6

Related Questions