# How to Use JJCollectionViewRoundFlowLayout with IGListCollectionView Delegate: Complete Integration Guide

> Master JJCollectionViewRoundFlowLayout with IGListCollectionView delegate. Integrate seamlessly using the SQCollectionRoundFlowLayout wrapper for dynamic list management.

- Repository: [Kingjiajie_Go/jjcollectionviewroundflowlayout](https://github.com/kingjiajie/jjcollectionviewroundflowlayout)
- Tags: how-to-guide
- Published: 2026-03-05

---

**Use the `SQCollectionRoundFlowLayout` wrapper class to bridge `JJCollectionViewRoundFlowLayout` with IGListKit by forwarding delegate calls to your `IGListSectionController` implementations.**

`JJCollectionViewRoundFlowLayout` provides rounded backgrounds, shadows, and borders for `UICollectionView` sections, but integrating it with IGListKit requires special handling since the `IGListAdapter` owns the collection view's delegate. In the `kingjiajie/jjcollectionviewroundflowlayout` repository, the `SQCollectionRoundFlowLayout` class solves this by routing `JJCollectionViewDelegateRoundFlowLayout` protocol methods to the appropriate section controllers.

## Architecture Overview

The integration relies on a delegation-forwarding pattern that preserves IGListKit's data-driven architecture while allowing per-section customization of rounded decorations.

| Component | Role | Key Source |
|-----------|------|------------|
| **`JJCollectionViewRoundFlowLayout`** | Core layout class that draws section background decorations, computes insets, shadows, and alignment. | [`JJCollectionViewRoundFlowLayout/Classes/JJCollectionViewRoundFlowLayout.h`](https://github.com/kingjiajie/jjcollectionviewroundflowlayout/blob/main/JJCollectionViewRoundFlowLayout/Classes/JJCollectionViewRoundFlowLayout.h) |
| **`JJCollectionViewDelegateRoundFlowLayout`** | Protocol defining per-section customization methods including configuration models and border insets. | [`JJCollectionViewRoundFlowLayout/Classes/JJCollectionViewRoundFlowLayout.h`](https://github.com/kingjiajie/jjcollectionviewroundflowlayout/blob/main/JJCollectionViewRoundFlowLayout/Classes/JJCollectionViewRoundFlowLayout.h) |
| **`SQCollectionRoundFlowLayout`** | Subclass that forwards all delegate calls to the `IGListAdapter`'s section controller for each index. | [`Example/JJCollectionViewRoundFlowLayout/SQCollectionRoundFlowLayout.h`](https://github.com/kingjiajie/jjcollectionviewroundflowlayout/blob/main/Example/JJCollectionViewRoundFlowLayout/SQCollectionRoundFlowLayout.h) <br> `Example/JJCollectionViewRoundFlowLayout/SQCollectionRoundFlowLayout.m` |
| **`IGListSectionController`** | Your subclass implements delegate methods to customize the rounded background for its specific section. | Referenced in `Example/JJCollectionViewRoundFlowLayout/IGListkitViewController.m` |

### Delegation Flow

When the layout needs configuration values, `SQCollectionRoundFlowLayout` queries the `IGListAdapter` to locate the section controller owning that section index. If the controller implements the required `JJCollectionViewDelegateRoundFlowLayout` method, the layout uses that value; otherwise, it returns sensible defaults like `UIEdgeInsetsZero`.

## Step-by-Step Integration Guide

### Installing the Dependency

Add the pod to your `Podfile` and run `pod install`:

```ruby
pod 'JJCollectionViewRoundFlowLayout'

```

### Setting Up the Adapter and Layout

Create an `IGListAdapter` and instantiate `SQCollectionRoundFlowLayout` with that adapter. The wrapper stores a weak reference to route delegate calls.

```objc
// Create the IGListAdapter
self.adapter = [[IGListAdapter alloc] initWithUpdater:IGListAdapterUpdater.new
                                       viewController:self
                                     workingRangeSize:2];

// Initialize the wrapper layout with the adapter
SQCollectionRoundFlowLayout *layout = [[SQCollectionRoundFlowLayout alloc]
                                       initWithIGListAdapter:self.adapter];

// Create the collection view
IGListCollectionView *collectionView = [[IGListCollectionView alloc]
    initWithFrame:self.view.bounds
    collectionViewLayout:layout];

collectionView.translatesAutoresizingMaskIntoConstraints = NO;
collectionView.backgroundColor = UIColor.whiteColor;

// Connect adapter to collection view
self.adapter.collectionView = collectionView;
self.adapter.dataSource = self;

```

### Implementing the Section Controller

Create a subclass of `IGListSectionController` that adopts `JJCollectionViewDelegateRoundFlowLayout`. Implement the optional methods to customize the rounded background, shadows, and alignment for that specific section.

```objc
@interface MyIGListSectionController : IGListSectionController
                                        <IGListSectionType,
                                         JJCollectionViewDelegateRoundFlowLayout>
@end

@implementation MyIGListSectionController

- (NSInteger)numberOfItems {
    return 5;
}

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView
                        layout:(UICollectionViewLayout *)layout
    borderEdgeInsertsForSectionAtIndex:(NSInteger)section {
    return UIEdgeInsetsMake(8.f, 10.f, 8.f, 10.f);
}

- (JJCollectionViewRoundConfigModel *)collectionView:(UICollectionView *)collectionView
                                               layout:(UICollectionViewLayout *)layout
                    configModelForSectionAtIndex:(NSInteger)section {
    JJCollectionViewRoundConfigModel *model = [[JJCollectionViewRoundConfigModel alloc] init];
    model.cornerRadius = (section == 2) ? 0.f : 10.f;
    model.backgroundColor = UIColor.whiteColor;
    model.shadowColor = [UIColor colorWithRed:204/255.0 green:204/255.0 blue:204/255.0 alpha:0.6];
    model.shadowOffset = CGSizeZero;
    model.shadowOpacity = 1.f;
    model.shadowRadius = 4.f;
    return model;
}

- (JJCollectionViewRoundFlowLayoutAlignmentType)collectionView:(UICollectionView *)collectionView
                                                         layout:(UICollectionViewLayout *)layout
                                         alignmentTypeAtSection:(NSInteger)section {
    return JJCollectionViewRoundFlowLayoutAlignmentTypeLeft;
}

- (UICollectionViewCell *)cellForItemAtIndex:(NSInteger)index {
    UICollectionViewCell *cell = [self.collectionContext 
        dequeueReusableCellOfClass:UICollectionViewCell.class
                forSectionController:self
                           atIndex:index];
    cell.backgroundColor = (index % 2 == 0) ? UIColor.redColor : UIColor.orangeColor;
    return cell;
}

@end

```

Return this section controller from your `IGListAdapterDataSource` implementation:

```objc
- (IGListSectionController<IGListSectionType> *)listAdapter:(IGListAdapter *)listAdapter
                               sectionControllerForObject:(id)object {
    MyIGListSectionController *controller = [[MyIGListSectionController alloc] init];
    controller.inset = UIEdgeInsetsMake(40.f, 20.f, 40.f, 20.f);
    controller.minimumLineSpacing = 10.f;
    controller.minimumInteritemSpacing = 5.f;
    return controller;
}

```

## Complete Implementation Example

The following view controller demonstrates the full wiring between IGListKit and the rounded layout, including adapter setup, layout initialization, and data source methods.

```objc
// IGListkitViewController.m
#import "IGListkitViewController.h"
#import <IGListKit/IGListKit.h>
@import JJCollectionViewRoundFlowLayout;
#import "SQCollectionRoundFlowLayout.h"
#import "MyIGListSectionController.h"

@interface IGListkitViewController () <IGListAdapterDataSource, IGListAdapterDelegate>
@property (strong, nonatomic) IGListCollectionView *collectionView;
@property (nonatomic, strong) IGListAdapter *adapter;
@end

@implementation IGListkitViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self setupAdapterAndLayout];
    [self layoutCollectionView];
}

- (void)setupAdapterAndLayout {
    self.adapter = [[IGListAdapter alloc] initWithUpdater:IGListAdapterUpdater.new
                                           viewController:self
                                         workingRangeSize:2];
    
    SQCollectionRoundFlowLayout *layout = [[SQCollectionRoundFlowLayout alloc] 
                                          initWithIGListAdapter:self.adapter];
    
    self.collectionView = [[IGListCollectionView alloc] 
        initWithFrame:self.view.bounds
        collectionViewLayout:layout];
    self.collectionView.translatesAutoresizingMaskIntoConstraints = NO;
    self.collectionView.backgroundColor = UIColor.whiteColor;
    
    self.adapter.collectionView = self.collectionView;
    self.adapter.dataSource = self;
    self.adapter.delegate = self;
    [self.view addSubview:self.collectionView];
}

- (void)layoutCollectionView {
    UIView *cv = self.collectionView;
    UIView *parent = self.view;
    [parent addConstraints:@[
        [NSLayoutConstraint constraintWithItem:cv attribute:NSLayoutAttributeTop
                                     relatedBy:NSLayoutRelationEqual
                                        toItem:parent attribute:NSLayoutAttributeTop multiplier:1 constant:0],
        [NSLayoutConstraint constraintWithItem:cv attribute:NSLayoutAttributeLeft
                                     relatedBy:NSLayoutRelationEqual
                                        toItem:parent attribute:NSLayoutAttributeLeft multiplier:1 constant:0],
        [NSLayoutConstraint constraintWithItem:cv attribute:NSLayoutAttributeBottom
                                     relatedBy:NSLayoutRelationEqual
                                        toItem:parent attribute:NSLayoutAttributeBottom multiplier:1 constant:0],
        [NSLayoutConstraint constraintWithItem:cv attribute:NSLayoutAttributeRight
                                     relatedBy:NSLayoutRelationEqual
                                        toItem:parent attribute:NSLayoutAttributeRight multiplier:1 constant:0],
    ]];
}

#pragma mark - IGListAdapterDataSource

- (NSArray<id<IGListDiffable>> *)objectsForListAdapter:(IGListAdapter *)listAdapter {
    return @[@"1", @"2", @"3", @"4", @"5", @"6", @"7"];
}

- (IGListSectionController<IGListSectionType> *)listAdapter:(IGListAdapter *)listAdapter
                               sectionControllerForObject:(id)object {
    MyIGListSectionController *controller = [[MyIGListSectionController alloc] init];
    controller.inset = UIEdgeInsetsMake(40.f, 20.f, 40.f, 20.f);
    controller.minimumLineSpacing = 10.f;
    controller.minimumInteritemSpacing = 5.f;
    return controller;
}

- (UIView *)emptyViewForListAdapter:(IGListAdapter *)listAdapter {
    return nil;
}

@end

```

## Key Source Files and Responsibilities

Understanding these specific files in the `kingjiajie/jjcollectionviewroundflowlayout` repository helps you customize the integration:

- **[`JJCollectionViewRoundFlowLayout/Classes/JJCollectionViewRoundFlowLayout.h`](https://github.com/kingjiajie/jjcollectionviewroundflowlayout/blob/main/JJCollectionViewRoundFlowLayout/Classes/JJCollectionViewRoundFlowLayout.h)** — Defines the core `JJCollectionViewRoundFlowLayout` class and the `JJCollectionViewDelegateRoundFlowLayout` protocol with methods like `configModelForSectionAtIndex:` and `borderEdgeInsertsForSectionAtIndex:`.

- **[`JJCollectionViewRoundFlowLayout/Classes/JJCollectionViewRoundConfigModel.h`](https://github.com/kingjiajie/jjcollectionviewroundflowlayout/blob/main/JJCollectionViewRoundFlowLayout/Classes/JJCollectionViewRoundConfigModel.h)** — Contains the model class holding visual properties: `cornerRadius`, `backgroundColor`, `shadowColor`, `shadowOpacity`, `shadowRadius`, and border settings.

- **`Example/JJCollectionViewRoundFlowLayout/SQCollectionRoundFlowLayout.m`** — Implements the forwarding logic in methods like `collectionView:layout:configModelForSectionAtIndex:` by querying the adapter via `[_adapter sectionControllerForObject:[_adapter objectAtSection:section]]` and forwarding to the controller if it responds to the selector.

- **`Example/JJCollectionViewRoundFlowLayout/IGListkitViewController.m`** — Reference implementation showing how to wire the adapter, layout, and data source together in a production view controller.

## Summary

- **Use `SQCollectionRoundFlowLayout`** as a drop-in replacement for `JJCollectionViewRoundFlowLayout` when working with IGListKit; it handles all delegate forwarding automatically.

- **Initialize with the adapter** by calling `initWithIGListAdapter:` to establish the forwarding chain.

- **Implement `JJCollectionViewDelegateRoundFlowLayout`** in your `IGListSectionController` subclasses to control corner radius, background color, shadows, and border insets per section.

- **Return configuration models** via `configModelForSectionAtIndex:` to customize the visual appearance without breaking IGListKit's data-driven architecture.

- **Reference the example files** in the repository's `Example/` directory for complete working implementations of the wrapper and view controller setup.

## Frequently Asked Questions

### How does `SQCollectionRoundFlowLayout` handle delegate methods without a traditional collection view delegate?

`SQCollectionRoundFlowLayout` overrides the delegate getter to return `self`, then implements each `JJCollectionViewDelegateRoundFlowLayout` method by querying the `IGListAdapter` for the section controller at the specified index. According to the source in `SQCollectionRoundFlowLayout.m`, it calls `[_adapter sectionControllerForObject:[_adapter objectAtSection:section]]` and checks if the returned controller responds to the delegate method using `respondsToSelector:` before forwarding the call.

### Can I use different corner radii for different sections in the same collection view?

Yes. Because the layout queries the section controller for each index via `configModelForSectionAtIndex:`, you can return different `JJCollectionViewRoundConfigModel` instances with varying `cornerRadius` values. In your `IGListSectionController` implementation, inspect the section parameter or instance variables to determine the appropriate radius, as shown in the example where `model.cornerRadius` is set conditionally based on the section index.

### What happens if my section controller does not implement a specific delegate method?

The wrapper provides safe defaults. In `SQCollectionRoundFlowLayout.m`, methods like `borderEdgeInsertsForSectionAtIndex:` return `UIEdgeInsetsZero` and `alignmentTypeAtSection:` returns the default alignment if the section controller does not implement the protocol method. This ensures the layout functions correctly even with partial protocol adoption.

### Do I need to set the collection view's delegate property manually when using this integration?

No. You should not set `collectionView.delegate` manually because `IGListAdapter` manages the delegate and data source. The `SQCollectionRoundFlowLayout` acts as its own delegate internally and forwards specific rounded-layout queries to your section controllers, allowing the adapter to maintain control over the standard collection view delegate pattern.