# Implementing Dark Mode Support for Rounded Collection View Sections in JJCollectionViewRoundFlowLayout

> Implement dark mode for rounded collection view sections using JJCollectionViewRoundFlowLayout. Dynamically provide colors for seamless adaptation.

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

---

**To enable automatic dark mode adaptation for rounded collection view sections, supply dynamic `UIColor` objects created with `colorWithDynamicProvider:` (Objective‑C) or `UIColor { ... }` (Swift) when building the `JJCollectionViewRoundConfigModel` in your delegate method.**

The `JJCollectionViewRoundFlowLayout` library by kingjiajie provides an elegant way to draw rounded backgrounds behind collection view sections. When implementing dark mode support for these rounded sections, you do not need to modify the layout engine itself—instead, you configure the visual model to return adaptive colors that automatically resolve based on the current interface style.

## How Dark Mode Works in the Layout

The library’s architecture already contains the necessary hooks to react to appearance changes. Three core components handle the rendering pipeline:

- **`JJCollectionViewRoundConfigModel`** ([`JJCollectionViewRoundConfigModel.h`](https://github.com/kingjiajie/jjcollectionviewroundflowlayout/blob/main/JJCollectionViewRoundConfigModel.h)) – Stores all visual parameters including `backgroundColor`, `borderColor`, and `shadowColor`.
- **`JJCollectionReusableView`** – The decoration view that renders the actual rounded background.
- **`JJCollectionViewRoundFlowLayout`** (`JJCollectionViewRoundFlowLayout.m`) – Coordinates between the delegate, attributes, and the decoration view.

When the system interface style changes, the layout automatically triggers color resolution through `resolvedColorWithTraitCollection:` (iOS 13+) and updates the view via `toChangeCollectionReusableViewRoundInfoWithLayoutAttributes:`.

### The Delegate Contract

Your primary integration point is the delegate method `collectionView:layout:configModelForSectionAtIndex:`. The model returned here must contain dynamic `UIColor` instances rather than static constants. As implemented in kingjiajie/jjcollectionviewroundflowlayout, the layout stores this model inside `JJCollectionViewRoundLayoutAttributes` and passes it to the decoration view during `applyLayoutAttributes:`.

### Automatic Trait Change Handling

Inside `JJCollectionViewRoundFlowLayout.m`, the decoration view implements `traitCollectionDidChange:` (lines 78‑84) to detect appearance switches:

```objc
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
    [super traitCollectionDidChange:previousTraitCollection];
    [self toChangeCollectionReusableViewRoundInfoWithLayoutAttributes:_myCacheAttr];
}

```

This method re-invokes the color application logic, which resolves the dynamic colors for the new trait collection (lines 90‑102):

```objc
if (@available(iOS 13.0, *)) {
    view.layer.backgroundColor = [model.backgroundColor resolvedColorWithTraitCollection:self.traitCollection].CGColor;
    view.layer.shadowColor    = [model.shadowColor resolvedColorWithTraitCollection:self.traitCollection].CGColor;
    view.layer.borderColor    = [model.borderColor resolvedColorWithTraitCollection:self.traitCollection].CGColor;
}

```

Because this plumbing already exists, you only need to provide dynamic colors in the delegate.

## Supplying Dynamic Colors in the Delegate

Return a `JJCollectionViewRoundConfigModel` instance where every color property uses a dynamic provider. This works for `backgroundColor`, `borderColor`, and `shadowColor`.

### Objective‑C Implementation

```objc
- (JJCollectionViewRoundConfigModel *)collectionView:(UICollectionView *)collectionView
                                             layout:(UICollectionViewLayout *)layout
                         configModelForSectionAtIndex:(NSInteger)section {

    JJCollectionViewRoundConfigModel *model = [[JJCollectionViewRoundConfigModel alloc] init];

    // Dynamic background color
    model.backgroundColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull tc) {
        return tc.userInterfaceStyle == UIUserInterfaceStyleDark ?
               [UIColor colorWithWhite:0.15 alpha:1.0] :   // Dark mode
               [UIColor colorWithWhite:0.95 alpha:1.0];   // Light mode
    }];

    // Dynamic border color
    model.borderColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull tc) {
        return tc.userInterfaceStyle == UIUserInterfaceStyleDark ?
               [UIColor lightGrayColor] :
               [UIColor darkGrayColor];
    }];

    model.cornerRadius = 12.0;
    model.borderWidth  = 1.0;

    // Dynamic shadow color
    model.shadowColor = [UIColor colorWithDynamicProvider:^UIColor * _Nonnull(UITraitCollection * _Nonnull tc) {
        return tc.userInterfaceStyle == UIUserInterfaceStyleDark ?
               [UIColor blackColor] :
               [UIColor colorWithWhite:0.8 alpha:1.0];
    }];

    return model;
}

```

### Swift Implementation

```swift
func collectionView(_ collectionView: UICollectionView,
                    layout: UICollectionViewLayout,
                    configModelForSectionAt section: Int) -> JJCollectionViewRoundConfigModel {

    let model = JJCollectionViewRoundConfigModel()
    model.backgroundColor = UIColor { trait in
        trait.userInterfaceStyle == .dark ?
            UIColor(white: 0.15, alpha: 1.0) :
            UIColor(white: 0.95, alpha: 1.0)
    }

    model.borderColor = UIColor { trait in
        trait.userInterfaceStyle == .dark ? .lightGray : .darkGray
    }

    model.cornerRadius = 12
    model.borderWidth  = 1

    model.shadowColor = UIColor { trait in
        trait.userInterfaceStyle == .dark ?
            .black :
            UIColor(white: 0.8, alpha: 1.0)
    }

    return model
}

```

## Verifying the Integration

To confirm that dark mode support is active:

1. Run the app on an iOS 13+ device or simulator.
2. Navigate to the collection view using `JJCollectionViewRoundFlowLayout`.
3. Toggle between Light and Dark appearance in Settings (or use the Environment Overrides panel in Xcode).
4. The rounded section backgrounds should update immediately without requiring a reload or view recreation.

The example project included in the repository demonstrates this pattern in `SixthViewController.m`, which uses dynamic providers for section backgrounds.

## Summary

- **Use dynamic `UIColor` objects** created with `colorWithDynamicProvider:` or Swift trailing closure syntax when constructing `JJCollectionViewRoundConfigModel`.
- **The library handles trait changes automatically** via `traitCollectionDidChange:` in `JJCollectionReusableView` and resolves colors using `resolvedColorWithTraitCollection:` (iOS 13+).
- **No modifications are required** to `JJCollectionViewRoundFlowLayout.m` or the decoration view source code.
- **All color properties**—`backgroundColor`, `borderColor`, and `shadowColor`—support dynamic values.

## Frequently Asked Questions

### Do I need to subclass JJCollectionViewRoundFlowLayout to support dark mode?

No. The layout already implements `traitCollectionDidChange:` and color resolution logic inside `JJCollectionReusableView`. You only need to return dynamic `UIColor` instances from the `collectionView:layout:configModelForSectionAtIndex:` delegate method.

### What is the minimum iOS version required for this approach?

Dynamic colors using `colorWithDynamicProvider:` and `resolvedColorWithTraitCollection:` require **iOS 13.0 or later**. The library’s color resolution code is wrapped in `@available(iOS 13.0, *)` checks, so it remains safe on earlier iOS versions, though dynamic switching will not occur.

### Can I use system semantic colors instead of custom dynamic providers?

Yes. You can assign system semantic colors like `UIColor.systemBackground` or `UIColor.secondarySystemFill` directly to the model properties. These colors are already dynamic and adapt automatically to the current interface style without requiring a custom provider block.

### Why don't my rounded sections update when I toggle dark mode in Settings?

Ensure that every color property in your `JJCollectionViewRoundConfigModel` is a dynamic `UIColor`. Static colors (e.g., `[UIColor whiteColor]` or `[UIColor blackColor]`) do not respond to trait changes. Also verify that your delegate is correctly returning the model and that you are testing on iOS 13 or later.