JJCollectionViewRoundFlowLayout: The Complete Solution for Rounded Section Backgrounds in iOS
JJCollectionViewRoundFlowLayout is a drop-in UICollectionViewFlowLayout subclass that uses decoration views to automatically draw rounded, styled backgrounds behind collection view sections without manual view management.
Managing visually distinct section backgrounds in UICollectionView typically requires complex calculations and manual view insertion, but the open-source library kingjiajie/jjcollectionviewroundflowlayout abstracts this complexity into a delegate-driven architecture. By extending the standard flow layout with per-section configuration models, this library enables developers to implement rounded corners, borders, shadows, and background images with minimal code while maintaining compatibility with irregular cell sizes and custom alignments.
What Makes JJCollectionViewRoundFlowLayout Different
Unlike standard UICollectionViewFlowLayout subclasses that only manage cell positioning, JJCollectionViewRoundFlowLayout introduces a dedicated decoration view layer rendered behind each section. This architectural choice decouples the background appearance from cell content, allowing the layout to calculate a bounding rectangle that encompasses cells, headers, and footers dynamically. The implementation in JJCollectionViewRoundFlowLayout.m computes this frame during the layout preparation phase, ensuring the rounded background adapts automatically to content changes.
Core Architecture and Features
Decoration View-Based Backgrounds
The layout creates a UIColor-filled CALayer (or image layer) whose cornerRadius and maskedCorners properties derive from JJCollectionViewRoundConfigModel. As defined in JJCollectionViewRoundConfigModel.h, this model encapsulates all visual attributes including backgroundColor, borderWidth, borderColor, and cornerRadius. The layer's frame equals the union of all items, headers, and footers within the section, guaranteeing the rounded shape tightly surrounds the visible content without manual geometry calculations.
Per-Section Configuration Model
Each section can define independent styling through the JJCollectionViewDelegateRoundFlowLayout protocol. The delegate method collectionView:layout:configModelForSectionAtIndex: returns a JJCollectionViewRoundConfigModel instance specific to that section, enabling distinct color schemes, corner radii, or background images per index. The layout queries this delegate during every layout invalidation, as implemented in JJCollectionViewRoundFlowLayout.h.
Flexible Header and Footer Handling
The layout provides granular control over whether headers and footers participate in the background rectangle. Boolean properties isCalculateHeader and isCalculateFooter offer global defaults, while delegate methods isCalculateHeaderViewIndex: and isCalculateFooterViewIndex: enable per-section exceptions. This prevents unwanted visual gaps when headers should remain visually separated from the rounded content area.
Cell Alignment and Irregular Sizes
JJCollectionViewRoundFlowLayout supports cell alignment independent of background positioning. The collectionCellAlignmentType property accepts values like JJCollectionViewFlowLayoutAlignmentTypeByCenter or JJCollectionViewFlowLayoutAlignmentTypeByRightAndStartR, defined in JJCollectionViewRoundFlowLayout+Alignment.h. When isCalculateTypeOpenIrregularitiesCell is enabled, the layout measures each cell's actual frame rather than assuming fixed sizes, ensuring correct background fitting for Pinterest-style or mosaic layouts.
Background Images and Touch Animations
Beyond solid colors, the layout supports bgImage properties on the configuration model to display stretched background images. Additionally, JJCollectionViewTouchAnimationConfigModel enables ripple-like touch animations on section backgrounds via isDecorationViewTouchAnimationEnable and the delegate method isDecorationViewShowAnimationAtIndex:. These animations can optionally propagate to contained cells through the isCellsAnimationEnable flag.
Implementation Examples
Basic Setup with Rounded Corners
Configure the layout and implement the delegate protocol to apply a uniform rounded background:
#import <JJCollectionViewRoundFlowLayout/JJCollectionViewRoundFlowLayout.h>
JJCollectionViewRoundFlowLayout *layout = [[JJCollectionViewRoundFlowLayout alloc] init];
layout.isCalculateHeader = YES;
layout.isCalculateFooter = YES;
self.collectionView.collectionViewLayout = layout;
#pragma mark - JJCollectionViewDelegateRoundFlowLayout
- (JJCollectionViewRoundConfigModel *)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout *)collectionViewLayout
configModelForSectionAtIndex:(NSInteger)section {
JJCollectionViewRoundConfigModel *model = [[JJCollectionViewRoundConfigModel alloc] init];
model.backgroundColor = [UIColor colorWithWhite:0.9 alpha:1.0];
model.cornerRadius = 12.0;
model.borderWidth = 1.0;
model.borderColor = [UIColor lightGrayColor];
return model;
}
See JJCollectionViewRoundFlowLayout.h and JJCollectionViewRoundConfigModel.h for complete property definitions.
Dynamic Per-Section Styling
Apply distinct backgrounds to different sections while conditionally including headers:
- (JJCollectionViewRoundConfigModel *)collectionView:(UICollectionView *)cv
layout:(UICollectionViewLayout *)layout
configModelForSectionAtIndex:(NSInteger)section {
JJCollectionViewRoundConfigModel *model = [[JJCollectionViewRoundConfigModel alloc] init];
if (section == 0) {
model.backgroundColor = [UIColor systemRedColor];
} else if (section == 1) {
model.backgroundColor = [UIColor systemBlueColor];
}
model.cornerRadius = 8.0;
return model;
}
- (BOOL)collectionView:(UICollectionView *)cv
layout:(UICollectionViewLayout *)layout
isCalculateHeaderViewIndex:(NSInteger)section {
return (section % 2 == 0);
}
Configuring Cell Alignment
Enable irregular cell size handling and specify alignment types:
layout.collectionCellAlignmentType = JJCollectionViewFlowLayoutAlignmentTypeByCenter;
layout.isCalculateTypeOpenIrregularitiesCell = YES;
- (JJCollectionViewRoundFlowLayoutAlignmentType)collectionView:(UICollectionView *)cv
layout:(UICollectionViewLayout *)layout
alignmentTypeAtSection:(NSInteger)section {
return JJCollectionViewFlowLayoutAlignmentTypeByRightAndStartR;
}
Reference JJCollectionViewRoundFlowLayout+Alignment.h for available alignment constants.
Adding Touch Ripple Effects
Implement background images with selective touch animations:
- (JJCollectionViewRoundConfigModel *)collectionView:(UICollectionView *)cv
layout:(UICollectionViewLayout *)layout
configModelForSectionAtIndex:(NSInteger)section {
JJCollectionViewRoundConfigModel *model = [[JJCollectionViewRoundConfigModel alloc] init];
model.bgImage = [UIImage imageNamed:@"sectionPattern"];
model.cornerRadius = 6.0;
return model;
}
- (BOOL)collectionView:(UICollectionView *)cv
layout:(UICollectionViewLayout *)layout
isDecorationViewShowAnimationAtIndex:(NSInteger)section {
return (section == 2);
}
- (JJCollectionViewTouchAnimationConfigModel *)collectionView:(UICollectionView *)cv
layout:(UICollectionViewLayout *)layout
animationConfigModelForSection:(NSInteger)section {
JJCollectionViewTouchAnimationConfigModel *animModel = [JJCollectionViewTouchAnimationConfigModel createDefaultModel];
animModel.endDuration = 0.6;
animModel.isCellsAnimationEnable = NO;
return animModel;
}
See JJCollectionViewTouchAnimationConfigModel.h for animation configuration options.
Summary
JJCollectionViewRoundFlowLayout abstracts the geometric complexity of drawing rounded section backgrounds in UICollectionView through a robust decoration view architecture. Key advantages include:
- Automatic background fitting that adapts to cells, headers, and footers via
JJCollectionViewRoundConfigModel - Per-section styling without subclassing, using the
JJCollectionViewDelegateRoundFlowLayoutprotocol - Flexible inclusion rules for headers and footers through
isCalculateHeaderViewIndex:andisCalculateFooterViewIndex: - Support for irregular cell sizes when
isCalculateTypeOpenIrregularitiesCellis enabled - Built-in touch animations and background image support via
JJCollectionViewTouchAnimationConfigModel - IGListKit compatibility through an explicit
delegateproperty that decouples fromcollectionView.delegate
Frequently Asked Questions
How does JJCollectionViewRoundFlowLayout differ from standard UICollectionViewFlowLayout?
Standard UICollectionViewFlowLayout manages cell positioning but provides no native mechanism for section backgrounds. JJCollectionViewRoundFlowLayout extends this by inserting a decoration view behind each section's content, calculated as the union of all items, headers, and footers. This decoration view renders the rounded background independently of cell layers, eliminating the need for manual view insertion or complex frame calculations in your view controller.
Can I use different corner radii for different sections?
Yes. The delegate method collectionView:layout:configModelForSectionAtIndex: returns a JJCollectionViewRoundConfigModel instance for each section individually. You can set distinct cornerRadius values, background colors, borders, or background images per section by returning different model configurations based on the section index provided in the method parameter.
Does it support IGListKit or other delegate-less collection view architectures?
Yes. The layout exposes a standalone delegate property that accepts any object conforming to JJCollectionViewDelegateRoundFlowLayout. This design decouples the layout delegate from collectionView.delegate, making it compatible with IGListKit or any architecture where the collection view's delegate is unavailable or managed by a separate component. Simply assign your layout configuration object directly to the layout's delegate property.
How do I handle sections with no cells?
Enable the isCanCalculateWhenRowEmpty property or implement the delegate method isCanCalculateWhenRowEmptyWithSection:. When activated, the layout calculates the background rectangle using only the header and footer frames, ensuring that empty sections still display their rounded background rather than collapsing to zero height. This is particularly useful for placeholder or loading states within collection views.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →