Skip to content

Instantly share code, notes, and snippets.

@viteinfinite
Last active December 18, 2015 05:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save viteinfinite/5735887 to your computer and use it in GitHub Desktop.
Save viteinfinite/5735887 to your computer and use it in GitHub Desktop.
Implementation of XBImageGalleryLayout used in the blog post "À la (re)découverte de la UICollectionView"
//
// XBImageGalleryLayout.m
//
// Created by Simone Civetta on 4/24/13.
// Copyright (c) 2013 Xebia IT Architects. All rights reserved.
//
#import "XBImageGalleryLayout.h"
#import <UICollectionView/UICollectionView.h>
static const CGFloat imageWitdh = 180.0f;
static const CGFloat imageHeight = 135.0f;
static const CGFloat imageLeftMargin = (320.0 - imageWitdh) / 2;
@implementation XBImageGalleryLayout
- (id)init
{
self = [super init];
if (self) {
// Taille des cellules
self.itemSize = CGSizeMake(imageWitdh, imageHeight);
// Configuration de l'aspect
self.minimumLineSpacing = -10; // Espace minimum entre les cellules
self.sectionInset = UIEdgeInsetsMake(0, imageLeftMargin, 0, imageLeftMargin); // "Padding"
// Direction de défilement
self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
}
return self;
}
- (NSArray*)layoutAttributesForElementsInRect:(CGRect)rect
{
NSArray *layoutAttributes = [super layoutAttributesForElementsInRect:rect];
CGFloat horizontalCenter = (CGRectGetWidth(self.collectionView.bounds) / 2.0f);
[layoutAttributes enumerateObjectsUsingBlock:^(UICollectionViewLayoutAttributes *layoutAttributes, NSUInteger idx, BOOL *stop) {
CGPoint centerInCollectionView = layoutAttributes.center;
CGPoint centerInMainView = [self.collectionView.superview convertPoint:centerInCollectionView
fromView:self.collectionView];
if (centerInMainView.x > -80 && centerInMainView.x < self.collectionView.frame.size.width + 80){
CGFloat translateYBy = [self translateYByOffset:centerInMainView.x fromCenter:horizontalCenter];
CGFloat scaleBy = [self scaleByOffset:centerInMainView.x fromCenter:horizontalCenter];
CGFloat alpha = [self alphaByOffset:centerInMainView.x fromCenter:horizontalCenter];
CATransform3D transform = CATransform3DIdentity;
transform = CATransform3DScale(transform, scaleBy, scaleBy, 1.0);
transform = CATransform3DTranslate(transform, 0.0, translateYBy, 0.0);
layoutAttributes.transform3D = transform;
layoutAttributes.alpha = alpha;
}
}];
return layoutAttributes;
}
#pragma mark - Attribute calculation
- (CGFloat)scaleByOffset:(float)x fromCenter:(float)horizontalCenter
{
CGFloat diff = x - horizontalCenter;
CGFloat scaleBy = [self transformValue:diff fromMin:-240.0 fromMax:240.0 toMin:0.6 toMax:1.0];
return scaleBy;
}
- (CGFloat)translateYByOffset:(float)x fromCenter:(float)horizontalCenter
{
CGFloat diff = x - horizontalCenter;
return [self transformValue:diff fromMin:-240.0 fromMax:240.0 toMin:50.0 toMax:0.0];
}
- (CGFloat)alphaByOffset:(float)x fromCenter:(float)horizontalCenter
{
CGFloat diff = x - horizontalCenter;
return [self transformValue:diff fromMin:-240.0 fromMax:240.0 toMin:0.1 toMax:1.0];
}
#pragma mark - Content offset
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset
withScrollingVelocity:(CGPoint)velocity
{
CGFloat offsetAdjustment = MAXFLOAT;
CGFloat horizontalOffset = proposedContentOffset.x + imageLeftMargin;
CGRect targetRect = CGRectMake(proposedContentOffset.x, 0, self.collectionView.bounds.size.width, self.collectionView.bounds.size.height);
NSArray *array = [super layoutAttributesForElementsInRect:targetRect];
for (UICollectionViewLayoutAttributes *layoutAttributes in array) {
CGFloat itemOffset = layoutAttributes.frame.origin.x;
if (fabsf(itemOffset - horizontalOffset) < fabsf(offsetAdjustment)) {
offsetAdjustment = itemOffset - horizontalOffset;
}
}
return CGPointMake(proposedContentOffset.x + offsetAdjustment, proposedContentOffset.y);
}
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
return YES;
}
- (NSUInteger)imageGallery:(XBImageGallery *)imageGallery pageForContentOffset:(CGPoint)contentOffset
{
return floor((contentOffset.x - imageWitdh / 2) / imageWitdh) + 1;
}
#pragma mark - Accessory Methods
- (CGFloat)transformValue:(CGFloat)x fromMin:(CGFloat)fromMin fromMax:(CGFloat)fromMax toMin:(CGFloat)toMin toMax:(CGFloat)toMax
{
CGFloat middle = (fromMax - fromMin) / 2.0;
return (middle - fabsf(x)) / (middle) * (toMax - toMin) + toMin;
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment