Last active
December 18, 2015 05:49
-
-
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"
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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