Search code examples
iosobjective-cuiscrollviewuicollectionviewuicollectionviewlayout

How to create a centered UICollectionView like in Spotify's Player


I am have a lot of difficulty trying to create a UICollectionView like in Spotify's Player that acts like this:

a busy cat

The problem for me is two fold.

1) How do I center the cells so that you can see the middle cell as well as the one of the left and right.

  • If I create cells that are square and add spacing between each cell, the cells are correctly displayed but are not centered.

2) With pagingEnabled = YES, the collectionview correctly swipes from one page to another. However, without the cells being centered, it simply moves the collection view over a page which is the width of the screen. So the question is how do you make the pages move so you get the effect above.

3) how do you animate the size of the cells as they move

  • I don't want to worry about this too much. If I can get that to work it would be great, but the harder problems are 1 and 2.

The code I have currently is a simple UICollectionView with normal delegate setup and custom UICollectionview cells that are squares. Maybe I neeed to subclass UICollectionViewFlowLayout? Or maybe I need to turn pagingEnabled to NO and then use custom swipe events? Would love any help!


Solution

  • As you have said in the comment you want that in the Objective-c code, there is a very famous library called iCarousel which can be helpful in completing your requirement.Link: https://github.com/nicklockwood/iCarousel

    You may use 'Rotary' or 'Linear' or some other style with little or no modification to implement the custom view

    To implement it you have implement only some delegate methods of it and it's working for ex:

    //specify the type you want to use in viewDidLoad
    _carousel.type = iCarouselTypeRotary;
    
    //Set the following delegate methods
    - (NSInteger)numberOfItemsInCarousel:(iCarousel *)carousel
    {
        //return the total number of items in the carousel
        return [_items count];
    }
    
    - (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSInteger)index reusingView:(UIView *)view
    {
        UILabel *label = nil;
    
        //create new view if no view is available for recycling
        if (view == nil)
        {
            //don't do anything specific to the index within
            //this `if (view == nil) {...}` statement because the view will be
            //recycled and used with other index values later
            view = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 200.0f, 200.0f)];
            ((UIImageView *)view).image = [UIImage imageNamed:@"page.png"];
            view.contentMode = UIViewContentModeCenter;
    
            label = [[UILabel alloc] initWithFrame:view.bounds];
            label.backgroundColor = [UIColor clearColor];
            label.textAlignment = NSTextAlignmentCenter;
            label.font = [label.font fontWithSize:50];
            label.tag = 1;
            [view addSubview:label];
        }
        else
        {
            //get a reference to the label in the recycled view
            label = (UILabel *)[view viewWithTag:1];
        }
    
        //set item label
        label.text = [_items[index] stringValue];
    
        return view;
    }
    
    - (CGFloat)carousel:(iCarousel *)carousel valueForOption:(iCarouselOption)option withDefault:(CGFloat)value
    {
        if (option == iCarouselOptionSpacing)
        {
            return value * 1.1;
        }
        return value;
    }
    

    You can check the full working demo from 'Examples/Basic iOS Example' which is included with the Github repository link

    As it is old and popular you can find some related tutorials for it and it will also be much stable than the custom code implementation