jjxtra
jjxtra

Reputation: 21180

How do I center the cells of a UICollectionView horizontally and vertically?

How do I vertically and horizontally center all the cells in a UICollectionView using UICollectionViewFlowLayout?

Flow layout leaves spacing on the right or bottom depending on the scroll direction. I want to set the same padding on all sides. I have played around with the sectionInset property of the UICollectionViewFlowLayout.

Upvotes: 8

Views: 8819

Answers (3)

Lee Probert
Lee Probert

Reputation: 10859

Subclass UICollectionViewFlowLayout and override the layoutAttributesForElementsInRect: method to align your UICollectionViewCells:

-(NSArray*)layoutAttributesForElementsInRect:(CGRect)rect {

NSArray* array = [super layoutAttributesForElementsInRect:rect];
CGRect visibleRect;
visibleRect.origin = self.collectionView.contentOffset;
visibleRect.size = self.collectionView.bounds.size;

for(UICollectionViewLayoutAttributes* attributes in array) {

    if(CGRectIntersectsRect(attributes.frame, rect)){

        CGFloat d = UIInterfaceOrientationIsPortrait(_orientation)?
        CGRectGetMidY(visibleRect)-attributes.center.y :
        CGRectGetMidX(visibleRect)-attributes.center.x;

        CGFloat w = visibleRect.size.width;
        CGFloat h = visibleRect.size.height;

        CGFloat dRatio = UIInterfaceOrientationIsPortrait(_orientation)? d/(h/2) : d/(w/2);

        CGFloat angle = MAX_ANGLE*dRatio; // an angle between 0 and MAX_ANGLE based on proximity to center
        CGFloat radians = DEGREES_TO_RADIANS(angle);

        debug = 0;

        CATransform3D rotationAndPerspectiveTransform = CATransform3DIdentity;
        rotationAndPerspectiveTransform.m34 = PERSPECTIVE;

        rotationAndPerspectiveTransform = UIInterfaceOrientationIsPortrait(_orientation)?
        CATransform3DRotate(rotationAndPerspectiveTransform, radians, 1.0f, 0.0f, 0.0f) :
        CATransform3DRotate(rotationAndPerspectiveTransform, radians, 0.0f, 1.0f, 0.0f);

        attributes.transform3D = rotationAndPerspectiveTransform;
    }
}

return array;
}

I've not edited this code for you and there are references to macros and instance variables so you'd need to tweak it to do what you want. This was used to create a coverflow style layout but the principles will be the same for you but without the 3D business. You need to set the section inset to guarantee a single row or column in your flow.

Upvotes: -1

Daniel Zhang
Daniel Zhang

Reputation: 5858

I'd suggest implementing the UICollectionViewDelegateFlowLayout protocol to dynamically achieve horizontal and vertical centering of your cells. From the UICollectionViewDelegateFlowLayout Protocol Reference:

The UICollectionViewDelegateFlowLayout protocol defines methods that let you coordinate with a UICollectionViewFlowLayout object to implement a grid-based layout. The methods of this protocol define the size of items and the spacing between items in the grid.

All of the methods in this protocol are optional. If you do not implement a particular method, the flow layout delegate uses values in its own properties for the appropriate spacing information.

The flow layout object expects the collection view’s delegate object to adopt this protocol. Therefore, implement this protocol on object assigned to your collection view’s delegate property.

You'll probably be most interested in the collectionView:layout:insetForSectionAtIndex: method that can be used to adjust the inset on all four sides of the screen using something like UIEdgeInsetsMake. You can determine the insets according to the screen size by subtracting the appropriate amount, like the size of the cells, from the corresponding screen dimension (vertical or horizontal). Then, divide by two to get equal insets for a particular dimension.

Upvotes: 5

Charan
Charan

Reputation: 4946

Used Section Inset?

Ok, try to play with minimumLineSpacing property and minimumInteritemSpacing property

minimumLineSpacing

For a vertically scrolling grid, this line spacing represents the minimum spacing between successive rows. For a horizontally scrolling grid, this value represents the minimum spacing between successive columns. This spacing is not applied to the space between the header and the first line or between the last line and the footer.

minimumInteritemSpacing

For a vertically scrolling grid, this spacing represents the minimum spacing between items in the same row. For a horizontally scrolling grid, this value represents the minimum spacing between items in the same column. This spacing is used to compute how many items can fit in a single line, but after the number of items is determined, the actual spacing may possibly be adjusted upward.

Upvotes: 1

Related Questions