27

I want to display only two cells in a row, no matter what the iPhone screen size is. Like, End result required

My storyboard contains a UICollectionView,connected by constraints.

Storyboard preview

The storyboard settings for the UICollectionView is, enter image description here

Now, when I run this in 6, 5s or below, only one cell appears in a row. The code I'd used is,

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
    return [categoryImages count];
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
    homePageCells *cell = (homePageCells *)[collectionView dequeueReusableCellWithReuseIdentifier:@"cells" forIndexPath:indexPath];
    cell.categoryName.text = [categoryNames objectAtIndex:indexPath.row];

    return cell;
}

I tried detecting the screen size and assigning appropriate cell size programmatically using the code,

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


    CGSize result = [[UIScreen mainScreen] bounds].size;
    NSLog(@"%f",result.height);
    if(result.height == 480)
    {
        //Load 3.5 inch xib
        sizes =CGSizeMake(170.f, 170.f);
        NSLog(@"3gs");
    }
    else if(result.height == 568)
    {
        //Load 4 inch xib
        sizes =CGSizeMake(130.f, 130.f);
        NSLog(@"5s");

    }
    else if(result.height == 667.000000)
    {
        //Load 4.7 inch xib
        sizes =CGSizeMake(160.f, 160.f);
        NSLog(@"6");

    }
    else
    {
        NSLog(@"else");

        sizes =CGSizeMake(170.f, 165.f);

    }
    return sizes;
}

But I also know that this isn't the right way, so please give me a right way to handle this.

rajesh s
  • 347
  • 1
  • 5
  • 12

3 Answers3

73

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, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {

   let padding: CGFloat =  50
   let collectionViewSize = collectionView.frame.size.width - padding

   return CGSizeMake(collectionViewSize/2, collectionViewSize/2)
   
}

Update: Swift 4.0

  func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let padding: CGFloat =  50
        let collectionViewSize = collectionView.frame.size.width - padding
        
        return CGSize(width: collectionViewSize/2, height: collectionViewSize/2)
    }

Note: I have answered the question considering the cells are square sized

Addition Information: Please make sure you make estimated size none https://i.stack.imgur.com/B9kmU.png

Rohit Pradhan
  • 3,867
  • 1
  • 21
  • 29
  • Thanks for saving my day. I'm so dumb, I didn't even think of this simple solution. Thanks a lot! – rajesh s Jul 15 '16 at 11:36
  • This really helps. Thanks for the answering and the question you have raised. – 21.kaw Jun 19 '17 at 17:14
  • 2
    This works great. Just need to add UICollectionViewDelegateFlowLayout to the class. – JoeGalind Jan 16 '18 at 05:10
  • 1
    my cells are not square and the width of the cells are twice the height of them how can I have two columns of that in my collection view ? – Saeed Rahmatolahi Jan 27 '18 at 07:38
  • 1
    Thank you so much, best answer! It helped me a lot – Diana Mar 26 '18 at 14:51
  • Just wanted to point out that your viewController should implement : `extension ViewController: UICollectionViewDelegateFlowLayout` is a MUST, in order for this method to work. Thanks anyway saved my day. – KarimIhab Oct 14 '18 at 12:41
  • not working for me, all the cells are aligned to centre of the collection view , one cell per row, in vertical direction. can anyone help where am I wrong? – Tahir Pasha Apr 16 '20 at 09:56
11

Xcode 8: Swift 3

I know this is an older question, but I found a few issues with accepted answer.

I had to use UICollectionViewDelegateFlowLayout which is not CollectionViewFlowLayout

Then

In it 'Padding' is of type Int and when you try to subtract it from the variable collectionViewSize it throws an error because they are different types. Very easy to fix however.

I just added : CGFloat to the line

Finally, while there is probably a better way to do it, I had to match the padding by adjusting the collectionView leading and trailing constraints.

So all in all this is what my code ended up looking like

extension LandingPageViewController: UICollectionViewDelegateFlowLayout {

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

    let padding: CGFloat = 25
    let collectionCellSize = collectionView.frame.size.width - padding

  return CGSize(width: collectionCellSize/2, height: collectionCellSize/2)

   }

}
RubberDucky4444
  • 2,330
  • 5
  • 38
  • 70
2
- (CGSize)collectionView:(UICollectionView *)collectionView
              layout:(UICollectionViewLayout *)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat padding = 50;
CGFloat cellSize = collectionView.frame.size.width - padding;
return CGSizeMake(cellSize / 2, cellSize / 2);
}
sanjeet
  • 1,539
  • 15
  • 37