Horizontal UICollectionView single row layout

14,609

Solution 1

Ok, I've done this as follows;

sticking with an item size of 288x180 for my case

1/. Set the item size

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
    return CGSizeMake(288, 180);
}

2/. Set insetForSectionAtIndex

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

3/. Set minimumInteritemSpacingForSectionAtIndex to ensure spacing

- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section 
{
    return 5;
}

4/. When creating the cell id did the following;

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    UICollectionViewCell* cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass([UICollectionViewCell class]) forIndexPath:indexPath];

    if (!cell)
    {
        cell  = [self.collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass([UICollectionViewCell class]) forIndexPath:indexPath];

        cell.contentView.width = 288;
        cell.contentView.backgroundColor = [UIColor whiteColor];

    }

    return cell;
}

5/. To achieve the paging effect correctly ensure collectionView.paging = NO and subclass UICollectionViewFlowLayout to use targetContentOffsetForProposedContentOffset for correctly setting the scrollview offset

Not sure if this is the best way but it has given me the desired result..

Solution 2

Create a collection view and set the height according to the height of the items in YOUR SECOND ROW and then set the scroll direction to Horizontal. Also

Here is an image attached, check the settings of the collection view accordingly.

enter image description here

The following method will set the cell width according to your second row. The first cell would be displayed in 3/4th of the screen and second cell 1/4th part.

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

return CGSizeMake( (self.view.frame.size.width / 4) * 3, "YOUR SECOND ROW ITEM HEIGHT");

}

I have done this for 5 cells on the screen Attaching the code below.

enter image description here

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

    return CGSizeMake( self.view.frame.size.width / 5, 70);

}

-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
    if(indexPath.row > pos)
    {
        if (indexPath.row - pos == 2) {
            pos = pos + 1;
        }
        [self changeDate];
    }
    else if (indexPath.row == pos)
    {
        NSLog(@"Do Nothing");
    }
    else
    {
        if (indexPath.row + 2 == pos) {
            pos = pos - 1;
        }
        [self changeDate1];
    }
    //NSLog(@"%@",[arrDate objectAtIndex:indexPath.row]);
}


-(void)changeDate
{
    if (pos<(arrDate.count - 2)) {
        pos=pos+1;
        [self.tpCollectionView selectItemAtIndexPath:[NSIndexPath indexPathForRow:pos inSection:0] animated:YES scrollPosition:UICollectionViewScrollPositionCenteredHorizontally];
        NSLog(@"%@",[arrDate objectAtIndex:pos]);
        self.lblMovieName.text =[arrDate objectAtIndex:pos];
    }
}
-(void)changeDate1
{
    if(pos>2)
    {
        pos=pos-1;
        [self.tpCollectionView selectItemAtIndexPath:[NSIndexPath indexPathForRow:pos inSection:0] animated:YES scrollPosition:UICollectionViewScrollPositionCenteredHorizontally];
        NSLog(@"%@",[arrDate objectAtIndex:pos]);
        self.lblMovieName.text =[arrDate objectAtIndex:pos];
    }
    else{

    }
}
Share:
14,609
MichealB1969
Author by

MichealB1969

Updated on June 15, 2022

Comments

  • MichealB1969
    MichealB1969 almost 2 years

    I'm trying to setup what should be a simple horizontal layout using UICollectionView, going around in circles without achieving the desired result so any pointer or examples would be gratefully appreciated.

    Probably little point in me pasting code as changed so often without success.

    The image shows two rows, the first is a single item and is the correct size and aligned correctly in the centre. The second row has 3 items, the first should be the same size as the item above, with the next item edge being just visible indicating another item. When the item is swiped to the left their should be 3 items visible — the main item fully visible in the centre and items 1 & 3 just visible at the left and right edges.

    I have tried setting paging on, changing insetForSectionAtIndex, minimumLineSpacingForSectionAtIndex, minimumInteritemSpacingForSectionAtIndex.


    Edit - 16th December

    I haven't explained or illustrated this very well, so have better illustrated below. I know how to create the collection view, set the item size etc but can not get the desired layout.

    This is a single row horizontal UICollectionView with one item always in full view and its neighbouring items in partial view indicating to the user there are more items to the left or right depending on the scroll position and item count.

    • when Item 1 is in full view, item 2 is in partial view
    • when Item 2 is in full view, item 1 and 3 are in partial view (left and right)
    • when Item 3 is in full view, item 2 is in partial view (left)
  • MichealB1969
    MichealB1969 over 8 years
    Many thanks for the suggestions but I'm not sure that answers the question, i have updated the question to better explain the requirement.
  • Jimbo
    Jimbo about 6 years
    Could you explain "subclass UICollectionViewFlowLayout to use targetContentOffsetForProposedContentOffset"? Everything was great until this point!