Display just two columns, with multiple rows in a CollectionView using storyboard

醉酒当歌 提交于 2019-12-09 04:08:33

问题


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

My storyboard contains a UICollectionView,connected by constraints.

The storyboard settings for the UICollectionView is,

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.


回答1:


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




回答2:


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)

   }

}



回答3:


- (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);
}



回答4:


I had problems with the bounds of the collectionView passed into sizeForItemAtIndexPath not being correct at that moment in time.

One fix for this would be to reload the cells in viewWillAppear to ensure the collectionView's bounds are correct.

Another is to use the UIScreen class.

-(instancetype)init: {
    self = [super init];
    if (self) {
        width = [[UIScreen mainScreen] bounds].size.width;
    }
    return self;
}

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

    // Two columns with spacing in between
    CGFloat size = ((width / 2) - (kSpacing * 2));
    return CGSizeMake(size, size);

}

In this case I'm instantiating the delegate as a separate class (hence the init) but it can be done just as easily as an extension.



来源:https://stackoverflow.com/questions/38394810/display-just-two-columns-with-multiple-rows-in-a-collectionview-using-storyboar

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!