Customizing Touch Animations for Section Backgrounds in JJCollectionViewRoundFlowLayout

JJCollectionViewRoundFlowLayout enables interactive press-and-release animations on section backgrounds by storing JJCollectionViewTouchAnimationConfigModel instances in layout attributes and executing scale transforms through the JJCollectionReusableView decoration view.

The JJCollectionViewRoundFlowLayout library extends UICollectionViewFlowLayout to add decorative backgrounds with rounded corners to collection view sections. When customizing touch animations for section backgrounds, the library leverages a specialized configuration model and delegate protocol to control scale factors, animation duration, and cell synchronization on a per-section basis.

Architecture of Touch Animation

The touch animation system consists of three coordinated components: a configuration model that defines animation parameters, layout attributes that store these configurations, and the decoration view that executes the animations in response to touch events.

The Configuration Model

Animation parameters are encapsulated in JJCollectionViewTouchAnimationConfigModel, defined in JJCollectionViewTouchAnimationConfigModel.h and implemented in JJCollectionViewTouchAnimationConfigModel.m. This model exposes properties for scale transforms and timing:

  • transformScaleSx and transformScaleSy – Scale factors for X and Y axes during the press state
  • startDuration – Duration of the press animation
  • endDuration – Duration of the release animation
  • isCellsAnimationEnable – Boolean flag indicating whether visible cells should animate synchronously with the background

The class provides a convenience factory method +createDefaultModel that returns a pre-configured instance with scale 0.98 and duration 0.2 seconds.

Layout Attributes and Delegate Wiring

During layout preparation in JJCollectionViewRoundFlowLayout.m (lines 99–107 and 111–121), the layout creates instances of JJCollectionViewRoundLayoutAttributes—a private subclass of UICollectionViewLayoutAttributes declared at lines 48–53. These attributes store two critical properties:

  1. isTouchAnimationEnable – A boolean flag enabling the feature for specific sections
  2. myTouchAnimationConfigModel – The configuration model governing animation behavior

The layout checks the delegate method collectionView:layout:isDecorationViewShowAnimationAtIndex: to determine section-level eligibility. If the delegate does not implement this method, the layout falls back to the global property isDecorationViewTouchAnimationEnable.

Touch Event Handling Lifecycle

The JJCollectionReusableView decoration view—defined inside JJCollectionViewRoundFlowLayout.m (lines 45–66)—intercepts touch events through standard UIKit methods:

  • touchesBegan:withEvent: – Reads myCacheAttr.myTouchAnimationConfigModel and animates the background to the press scale over startDuration. If isCellsAnimationEnable is YES, it simultaneously scales all visible cells in the same section.
  • touchesEnded:withEvent: and touchesCancelled:withEvent: – Animate the background and cells back to identity transform (scale 1.0) using endDuration.
  • decorationViewUserDidSelectEvent – Forwards completed tap events to the optional delegate method collectionView:didSelectDecorationViewAtIndexPath:.

Implementing Touch Animations

To activate and customize these animations, configure the layout properties and implement the required delegate methods from JJCollectionViewDelegateRoundFlowLayout.

Enable Global Animation

Set the property on the layout instance to enable default animations for all sections:

JJCollectionViewRoundFlowLayout *layout = (JJCollectionViewRoundFlowLayout *)self.collectionView.collectionViewLayout;
layout.isDecorationViewTouchAnimationEnable = YES;   // Applies default config to all sections

Custom Configuration Per Section

Implement collectionView:layout:animationConfigModelForSection: to return a tailored configuration model:

- (JJCollectionViewTouchAnimationConfigModel *)collectionView:(UICollectionView *)collectionView
                                                       layout:(UICollectionViewLayout *)layout
                                animationConfigModelForSection:(NSInteger)section {
    
    JJCollectionViewTouchAnimationConfigModel *model = [JJCollectionViewTouchAnimationConfigModel createDefaultModel];
    model.transformScaleSx = 0.95;      // Shrink to 95% on press
    model.transformScaleSy = 0.95;
    model.startDuration   = 0.15;      // Fast 150ms press animation
    model.endDuration     = 0.25;      // Slower 250ms release animation
    model.isCellsAnimationEnable = NO; // Restrict animation to background only
    return model;
}

Conditional Animation by Section

Restrict animation to specific sections by implementing the boolean delegate method:

- (BOOL)collectionView:(UICollectionView *)collectionView
                layout:(UICollectionViewLayout *)layout
isDecorationViewShowAnimationAtIndex:(NSInteger)section {
    // Enable only for even-numbered sections
    return (section % 2 == 0);
}

Handling Background Tap Events

Detect user taps on the section background to trigger navigation or selection logic:

- (void)collectionView:(UICollectionView *)collectionView
                didSelectDecorationViewAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(@"User tapped background of section %ld", (long)indexPath.section);
    // Insert navigation or state change logic here
}

Complete Integration Example

#import "JJCollectionViewRoundFlowLayout.h"
#import "JJCollectionViewTouchAnimationConfigModel.h"

@interface ViewController () <JJCollectionViewDelegateRoundFlowLayout>
@property (nonatomic, strong) UICollectionView *collectionView;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    JJCollectionViewRoundFlowLayout *layout = [[JJCollectionViewRoundFlowLayout alloc] init];
    layout.delegate = self;  // Required for touch animation delegate methods
    
    self.collectionView = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:layout];
    self.collectionView.dataSource = self;
    [self.view addSubview:self.collectionView];
}

#pragma mark - JJCollectionViewDelegateRoundFlowLayout

- (JJCollectionViewTouchAnimationConfigModel *)collectionView:(UICollectionView *)cv
                                                       layout:(UICollectionViewLayout *)layout
                                animationConfigModelForSection:(NSInteger)section {
    JJCollectionViewTouchAnimationConfigModel *cfg = [JJCollectionViewTouchAnimationConfigModel createDefaultModel];
    cfg.transformScaleSx = 0.92;
    cfg.transformScaleSy = 0.92;
    cfg.startDuration   = 0.12;
    cfg.endDuration     = 0.2;
    cfg.isCellsAnimationEnable = YES;
    return cfg;
}

- (void)collectionView:(UICollectionView *)cv
                didSelectDecorationViewAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(@"Section %ld background tapped", (long)indexPath.section);
}

@end

Summary

  • JJCollectionViewTouchAnimationConfigModel defines scale factors, durations, and cell synchronization settings in JJCollectionViewTouchAnimationConfigModel.h.
  • The layout stores animation configurations in JJCollectionViewRoundLayoutAttributes during prepareLayout (lines 99–121 of JJCollectionViewRoundFlowLayout.m).
  • Delegate methods in JJCollectionViewDelegateRoundFlowLayout control enablement per section and supply custom configuration models.
  • JJCollectionReusableView executes the animations inside touchesBegan:, touchesEnded:, and touchesCancelled: (lines 45–66 of JJCollectionViewRoundFlowLayout.m).
  • Background tap events propagate through didSelectDecorationViewAtIndexPath: for handling selection logic.

Frequently Asked Questions

How do I disable touch animations for specific sections while keeping them enabled globally?

Set layout.isDecorationViewTouchAnimationEnable = YES on the layout instance, then implement the delegate method collectionView:layout:isDecorationViewShowAnimationAtIndex: and return NO for sections that should remain static. This overrides the global setting on a per-section basis.

Can I animate the collection view cells along with the section background?

Yes. Set the isCellsAnimationEnable property to YES on your JJCollectionViewTouchAnimationConfigModel instance before returning it from collectionView:layout:animationConfigModelForSection:. When enabled, the decoration view automatically synchronizes scale animations with all visible cells in the touched section.

What are the default animation parameters if I don't provide a custom configuration?

If the delegate does not implement collectionView:layout:animationConfigModelForSection:, the layout automatically creates a default model via [JJCollectionViewTouchAnimationConfigModel createDefaultModel]. This applies a scale transform of 0.98 on both axes with animation durations of 0.2 seconds for both press and release phases, and enables cell animation by default.

How do I detect when a user finishes tapping the section background?

Implement the optional delegate method collectionView:didSelectDecorationViewAtIndexPath: declared in JJCollectionViewRoundFlowLayout.h. The system calls this method after the touch ends and the release animation completes, providing the NSIndexPath of the affected section.

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 →