How to Use Background Images for Collection View Sections with Rounded Corners

JJCollectionViewRoundFlowLayout draws a decoration view behind each section that clips a background image to rounded corners using the bgImage property in JJCollectionViewRoundConfigModel.

Adding visual depth to UICollectionView sections typically requires complex manual calculations, but the open-source library kingjiajie/jjcollectionviewroundflowlayout automates this by rendering a dedicated background layer behind each section. This guide explains how to configure section-specific background images with rounded corners, borders, and shadows while maintaining support for dynamic type and dark mode changes.

Implementation Overview

The layout engine creates a decoration view (JJCollectionReusableView) for every section. When you provide a JJCollectionViewRoundConfigModel via the delegate method configModelForSectionAtIndex:, the layout inspects the bgImage property. If non-nil, it instantiates an internal UIImageView, sizes it to the computed section frame (including headers, footers, and irregular cell heights), and applies the same corner radius and masked corners used for the background color layer.

Key source files involved:

  • JJCollectionViewRoundFlowLayout.h / .m – Defines the layout, delegate protocol, and decoration view registration
  • JJCollectionViewRoundConfigModel.h / .m – Stores visual parameters including bgImage, cornerRadius, and borderWidth
  • JJCollectionReusableView (inner class inside JJCollectionViewRoundFlowLayout.m around line 62) – Renders the background layer and handles image updates

Step-by-Step Configuration

1. Register the Layout

Initialize JJCollectionViewRoundFlowLayout and assign it to your collection view. Ensure isRoundEnabled remains YES (the default) to activate background rendering.

JJCollectionViewRoundFlowLayout *layout = [[JJCollectionViewRoundFlowLayout alloc] init];
layout.isRoundEnabled = YES;                           // Required for background drawing
layout.isDecorationViewTouchAnimationEnable = NO;    // Optional tap feedback
collectionView.collectionViewLayout = layout;

2. Adopt the Delegate Protocol

Conform to JJCollectionViewDelegateRoundFlowLayout and implement the configuration method. The delegate returns a model instance for each section index.

@interface MyViewController () <JJCollectionViewDelegateRoundFlowLayout>
@end

- (JJCollectionViewRoundConfigModel *)collectionView:(UICollectionView *)collectionView
                                            layout:(UICollectionViewLayout *)collectionViewLayout
                        configModelForSectionAtIndex:(NSInteger)section {
    
    JJCollectionViewRoundConfigModel *model = [[JJCollectionViewRoundConfigModel alloc] init];
    
    // Visual styling
    model.cornerRadius = 12.0;
    model.borderWidth  = 1.0;
    model.borderColor  = [UIColor lightGrayColor];
    
    // 👉 Set the background image (UIImage *)
    NSString *imageName = (section % 2 == 0) ? @"sectionBgA" : @"sectionBgB";
    model.bgImage = [UIImage imageNamed:imageName];
    
    return model;
}

3. Adjust Background Insets

By default, the decoration view fills the entire section frame. To create padding between the image and the section edges without affecting cell spacing, implement borderEdgeInsertsForSectionAtIndex:.

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView
                        layout:(UICollectionViewLayout *)collectionViewLayout
       borderEdgeInsertsForSectionAtIndex:(NSInteger)section {
    return UIEdgeInsetsMake(8, 12, 8, 12); // Top, Left, Bottom, Right
}

How It Works Under the Hood

Decoration View Architecture

During prepareLayout in JJCollectionViewRoundFlowLayout.m, the layout registers JJCollectionReusableView as a supplementary view of kind JJCollectionViewRoundSection. For each section, the layout queries your delegate for a JJCollectionViewRoundConfigModel. If bgImage exists, the reusable view creates an internal UIImageView named myBGImageView and inserts it into the view hierarchy.

Configuration Model Properties

The JJCollectionViewRoundConfigModel class (defined in JJCollectionViewRoundConfigModel.h) encapsulates all visual parameters:

  • bgImage (UIImage *) – The image displayed behind section cells
  • cornerRadius (CGFloat) – Applied to both the background layer and the image view via layer.cornerRadius
  • maskedCorners (CACornerMask) – Selects which corners to round when using iOS 11+ APIs
  • borderWidth and borderColor – Drawn around the clipped image boundary

Trait Collection Updates

The decoration view implements traitCollectionDidChange: to re-apply colors and shadows when the system appearance transitions (e.g., Light to Dark mode). This ensures the background image and its border remain visually consistent without requiring manual reloads.

Advanced Customization

Image Content Modes

The internal image view uses UIViewContentModeScaleToFill by default. If you require aspect fitting or filling, you must modify the layout’s internal decoration view subclass or manually adjust the image asset sizing, as the current public API in JJCollectionViewRoundConfigModel does not expose the contentMode property directly.

Irregular Cell Sizes

When isCalculateTypeOpenIrregularitiesCell is enabled on the layout, the decoration view automatically resizes to encompass cells with varying heights, ensuring the background image covers the entire section bounds including the tallest cell.

Summary

  • JJCollectionViewRoundFlowLayout renders section backgrounds through a dedicated decoration view system defined in JJCollectionViewRoundFlowLayout.m.
  • Set the bgImage property on JJCollectionViewRoundConfigModel to display an image clipped to the same rounded corners as the section background.
  • Implement configModelForSectionAtIndex: to provide per-section configuration and borderEdgeInsertsForSectionAtIndex: to control padding.
  • The layout automatically handles trait collection changes and supports headers, footers, and irregular cell layouts.

Frequently Asked Questions

How do I enable rounded corners only on specific corners of the background image?

Set the maskedCorners property on your JJCollectionViewRoundConfigModel before returning it from configModelForSectionAtIndex:. This property accepts a CACornerMask (e.g., kCALayerMinXMinYCorner | kCALayerMaxXMinYCorner for top corners only) and is applied to both the background layer and the internal UIImageView inside JJCollectionReusableView.

Can I use a different background image for each section?

Yes. The delegate method configModelForSectionAtIndex: receives the section index as a parameter. Return a distinct JJCollectionViewRoundConfigModel instance for each section with a unique bgImage assigned. The layout caches these attributes and updates the corresponding decoration views during layout invalidation cycles.

What happens to the background image when the device rotates or traits change?

The decoration view implements traitCollectionDidChange: to detect appearance transitions. While the image asset itself remains static, the layout recalculates the section frame and reapplies corner masks and borders automatically. For dynamic image switching (e.g., light/dark variants), invalidate the layout or return a different image from the delegate when the trait collection changes.

Does the background image support transparency and shadows?

Yes. The JJCollectionViewRoundConfigModel includes shadowColor, shadowOffset, and shadowOpacity properties. These apply to the decoration view’s layer, which sits behind the cells. If bgImage contains an alpha channel, the shadow renders correctly behind the visible portions of the image, creating a layered depth effect as calculated in applyLayoutAttributes:.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →