Files
IOS7ScrollViews/iOS7ScrollViews/SVSpringyFlowLayout.m
Pierre Felgines 9e02405171 Fix Apple bug
2013-07-04 13:49:39 +02:00

70 lines
2.4 KiB
Objective-C

//
// SVSpringyFlowLayout.m
// iOS7ScrollViews
//
// Created by Pierre Felgines on 20/06/13.
// Copyright (c) 2013 Pierre Felgines. All rights reserved.
//
#import "SVSpringyFlowLayout.h"
@implementation SVSpringyFlowLayout {
UIDynamicAnimator * _dynamicAnimator;
}
- (void)prepareLayout {
[super prepareLayout];
if (!_dynamicAnimator) {
_dynamicAnimator = [[UIDynamicAnimator alloc] initWithCollectionViewLayout:self];
CGSize contentSize = [self collectionViewContentSize];
NSArray * items = [super layoutAttributesForElementsInRect:CGRectMake(0, 0, contentSize.width, contentSize.height)];
for (UICollectionViewLayoutAttributes * item in items) {
UIAttachmentBehavior * spring = [[UIAttachmentBehavior alloc] initWithItem:item attachedToAnchor:[item center]];
spring.length = 0;
spring.damping = 0.5f;
spring.frequency = 0.8f;
[_dynamicAnimator addBehavior:spring];
}
}
}
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
return [_dynamicAnimator itemsInRect:rect];
}
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {
return [_dynamicAnimator layoutAttributesForCellAtIndexPath:indexPath];
}
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
UIScrollView * scrollView = self.collectionView;
CGFloat scrollDelta = newBounds.origin.y - scrollView.bounds.origin.y;
CGPoint touchLocation = [scrollView.panGestureRecognizer locationInView:scrollView];
for (UIAttachmentBehavior * spring in _dynamicAnimator.behaviors) {
CGPoint anchorPoint = spring.anchorPoint;
CGFloat distanceFromTouch = fabsf(touchLocation.y - anchorPoint.y);
CGFloat scrollResistance = distanceFromTouch / 500.0f;
UICollectionViewLayoutAttributes * item = [spring.items firstObject];
CGPoint center = item.center;
/* Original Code from Apple in WWDC video */
// center.y += MIN(scrollDelta, scrollDelta * scrollResistance);
/* Correction */
center.y += MIN(fabs(scrollDelta), fabs(scrollDelta * scrollResistance)) * scrollDelta / fabs(scrollDelta);
item.center = center;
[_dynamicAnimator updateItemFromCurrentState:item];
}
return NO;
}
@end