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:
transformScaleSxandtransformScaleSy– Scale factors for X and Y axes during the press statestartDuration– Duration of the press animationendDuration– Duration of the release animationisCellsAnimationEnable– 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:
isTouchAnimationEnable– A boolean flag enabling the feature for specific sectionsmyTouchAnimationConfigModel– 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:– ReadsmyCacheAttr.myTouchAnimationConfigModeland animates the background to the press scale overstartDuration. IfisCellsAnimationEnableisYES, it simultaneously scales all visible cells in the same section.touchesEnded:withEvent:andtouchesCancelled:withEvent:– Animate the background and cells back to identity transform (scale 1.0) usingendDuration.decorationViewUserDidSelectEvent– Forwards completed tap events to the optional delegate methodcollectionView: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
JJCollectionViewTouchAnimationConfigModeldefines scale factors, durations, and cell synchronization settings inJJCollectionViewTouchAnimationConfigModel.h.- The layout stores animation configurations in
JJCollectionViewRoundLayoutAttributesduringprepareLayout(lines 99–121 ofJJCollectionViewRoundFlowLayout.m). - Delegate methods in
JJCollectionViewDelegateRoundFlowLayoutcontrol enablement per section and supply custom configuration models. JJCollectionReusableViewexecutes the animations insidetouchesBegan:,touchesEnded:, andtouchesCancelled:(lines 45–66 ofJJCollectionViewRoundFlowLayout.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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →