Per-Section Cell Alignment Customization in JJCollectionViewRoundFlowLayout: A Complete Guide

To customize cell alignment per section in JJCollectionViewRoundFlowLayout, implement the delegate method collectionView:layout:alignmentTypeAtSection: and return the desired JJCollectionViewRoundFlowLayoutAlignmentType enum value for each section.

JJCollectionViewRoundFlowLayout is a drop-in replacement for UICollectionViewFlowLayout that adds rounded background decoration and granular per-section cell alignment capabilities. Available in the kingjiajie/jjcollectionviewroundflowlayout repository, this layout allows individual sections to use left, center, right, or system-default alignment without affecting other sections.

How Per-Section Alignment Works in JJCollectionViewRoundFlowLayout

The layout achieves per-section alignment through a delegate protocol that extends the standard UIKit flow layout delegate. The JJCollectionViewDelegateRoundFlowLayout protocol defines the method collectionView:layout:alignmentTypeAtSection:, which the layout queries for each section during its layout calculation.

The method returns a value from the JJCollectionViewRoundFlowLayoutAlignmentType enum defined in JJCollectionViewFlowLayoutConfig.h:

  • JJCollectionViewFlowLayoutAlignmentTypeBySystem – Uses the standard UIKit flow layout behavior
  • JJCollectionViewFlowLayoutAlignmentTypeByLeft – Aligns cells to the left edge of the section
  • JJCollectionViewFlowLayoutAlignmentTypeByCenter – Centers cells within the section width
  • JJCollectionViewFlowLayoutAlignmentTypeByRight – Aligns cells to the right edge
  • JJCollectionViewFlowLayoutAlignmentTypeByRightAndStartR – Right-aligns cells while preserving the original item order (reverse-right alignment)

Implementing the Delegate Protocol

To enable per-section alignment, conform your view controller or data source to JJCollectionViewDelegateRoundFlowLayout and implement the alignment method.

#pragma mark - JJCollectionViewDelegateRoundFlowLayout

- (JJCollectionViewRoundFlowLayoutAlignmentType)collectionView:(UICollectionView *)collectionView
                                                      layout:(UICollectionViewLayout *)collectionViewLayout
                                         alignmentTypeAtSection:(NSInteger)section {
    switch (section) {
        case 0:
            return JJCollectionViewFlowLayoutAlignmentTypeByLeft;
        case 1:
            return JJCollectionViewFlowLayoutAlignmentTypeByCenter;
        case 2:
            return JJCollectionViewFlowLayoutAlignmentTypeByRight;
        default:
            return JJCollectionViewFlowLayoutAlignmentTypeBySystem;
    }
}

When the collection view performs layout, JJCollectionViewRoundFlowLayout automatically queries this delegate method for each section and applies the specified alignment algorithm to the cells in that section.

Alignment Algorithms and Implementation Details

The actual positioning logic resides in JJCollectionViewRoundFlowLayout+Alignment.m. The layout processes alignment in three distinct phases:

Cell Grouping by Y-Center Line

First, the layout groups cells that share the same vertical position. The method groupLayoutAttributesForElementsByYLineWithLayoutAttributesAttrs: in JJCollectionViewRoundFlowLayout+Alignment.m (lines 30-45) iterates through layout attributes and groups them by their Y-center coordinate, ensuring that cells on the same row are aligned together.

Alignment Strategy Selection

The method analysisCellSettingFrameWithLayoutAttributesAttrs:toChangeAttributesAttrsList:cellAlignmentType: (lines 63-81) determines whether to apply custom alignment or fall back to the system layout. If the alignment type is BySystem, it returns immediately; otherwise, it proceeds to the specific alignment implementation.

Concrete Alignment Helpers

The method evaluatedAllCellSettingFrameWithLayoutAttributesAttrs:toChangeAttributesAttrsList:cellAlignmentType: (lines 84-108) dispatches to the concrete alignment routines:

  • evaluatedCellSettingFrameByLeft... – Calculates the left edge based on section insets and minimum inter-item spacing, then sets frame.origin.x for each cell in the row
  • evaluatedCellSettingFrameByCenter... – Computes the total width of the row content, calculates the center offset, and distributes cells from the center outward
  • evaluatedCellSettingFrameByRight... – Aligns cells to the right edge of the section, accounting for right section insets

These helpers utilize utility methods from JJCollectionViewFlowLayoutUtils.h to retrieve section insets and minimum inter-item spacing values.

Configuration Options and Fallback Behavior

You can specify a default alignment for all sections by setting the collectionCellAlignmentType property on the layout instance:

JJCollectionViewRoundFlowLayout *layout = [[JJCollectionViewRoundFlowLayout alloc] init];
layout.collectionCellAlignmentType = JJCollectionViewFlowLayoutAlignmentTypeByCenter;

When a delegate implements collectionView:layout:alignmentTypeAtSection:, the delegate method takes precedence over the global property for that specific section. Sections without a delegate implementation use the value from collectionCellAlignmentType, or JJCollectionViewFlowLayoutAlignmentTypeBySystem if no value is set.

Summary

  • JJCollectionViewRoundFlowLayout extends UICollectionViewFlowLayout to support per-section cell alignment and rounded backgrounds.
  • Implement JJCollectionViewDelegateRoundFlowLayout and override collectionView:layout:alignmentTypeAtSection: to specify alignment per section.
  • Choose from left, center, right, reverse-right, or system alignment types defined in JJCollectionViewFlowLayoutConfig.h.
  • The layout groups cells by Y-center line in JJCollectionViewRoundFlowLayout+Alignment.m, then applies specific alignment algorithms that calculate frame origins based on section insets and spacing.
  • Set collectionCellAlignmentType for a global default; delegate methods override this per section.

Frequently Asked Questions

How do I left-align cells in only one specific section while keeping others default?

Implement the delegate method collectionView:layout:alignmentTypeAtSection: and return JJCollectionViewFlowLayoutAlignmentTypeByLeft for the target section index, and JJCollectionViewFlowLayoutAlignmentTypeBySystem for all others. The layout automatically applies the specified alignment only to cells in that section while leaving other sections unchanged.

What is the difference between ByRight and ByRightAndStartR alignment types?

JJCollectionViewFlowLayoutAlignmentTypeByRight aligns cells to the right edge of the section but may reverse the visual order of items depending on the layout calculation. JJCollectionViewFlowLayoutAlignmentTypeByRightAndStartR (reverse-right) also aligns to the right edge but explicitly preserves the original item order from the data source, ensuring that the first item appears at the top-left of the right-aligned group.

Can I use per-section alignment without implementing the delegate protocol?

Yes, but with limitations. You can set the collectionCellAlignmentType property on the layout instance to apply a single alignment type to all sections globally. However, to achieve different alignments for different sections (per-section customization), you must implement the JJCollectionViewDelegateRoundFlowLayout protocol and provide section-specific logic in collectionView:layout:alignmentTypeAtSection:.

Where does the actual alignment calculation happen in the source code?

The alignment algorithms are implemented in JJCollectionViewRoundFlowLayout+Alignment.m. The entry point is analysisCellSettingFrameWithLayoutAttributesAttrs:toChangeAttributesAttrsList:cellAlignmentType:, which dispatches to evaluatedAllCellSettingFrameWithLayoutAttributesAttrs:toChangeAttributesAttrsList:cellAlignmentType:. This method then calls specific helpers like evaluatedCellSettingFrameByLeft..., ...ByCenter..., and ...ByRight... to calculate and update the frame.origin.x values for each cell based on section insets and spacing values retrieved from JJCollectionViewFlowLayoutUtils.

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 →