UICollectionViewCell水平縮放,中間大兩邊小效果的實現
//
// CollectionViewFlowLayout.h
// HorizontalScale
//
// Created by zmx on 16/3/15.
// Copyright © 2016年 zmx. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface CollectionViewFlowLayout : UICollectionViewFlowLayout
@end
//
// CollectionViewFlowLayout.m
// HorizontalScale
//
// Created by zmx on 16/3/15.
// Copyright © 2016年 zmx. All rights reserved.
//
#import "CollectionViewFlowLayout.h"
@implementation CollectionViewFlowLayout
- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect {
NSArray *attrs = [selfdeepCopyWithArray:[superlayoutAttributesForElementsInRect:rect]];
CGFloat contentOffsetX = self.collectionView.contentOffset.x;
CGFloat collectionViewCenterX = self.collectionView.frame.size.width * 0.5;
for (UICollectionViewLayoutAttributes *attr in attrs) {
CGFloat scale = 1 - fabs(attr.center.x - contentOffsetX - collectionViewCenterX) / self.collectionView
attr.transform = CGAffineTransformMakeScale(scale, scale);
}
return attrs;
}
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
return YES;
}
// 每次都有圖片居中
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity {
CGRect rect = CGRectMake(proposedContentOffset.x, 0, self.collectionView.bounds.size.width, self.collectionView.bounds.size.height);
NSArray *attrs = [superlayoutAttributesForElementsInRect:rect];
CGFloat contentOffsetX = self.collectionView.contentOffset.x;
CGFloat collectionViewCenterX = self.collectionView.frame.size.width * 0.5;
CGFloat minDistance = MAXFLOAT;
for (UICollectionViewLayoutAttributes *attr in attrs) {
CGFloat distance = attr.center.x - contentOffsetX - collectionViewCenterX;
if (fabs(distance) < fabs(minDistance)) {
minDistance = distance;
}
}
proposedContentOffset.x += minDistance;
return proposedContentOffset;
}
// UICollectionViewFlowLayout has cached frame mismatch for index path這個警告來源主要是在使用layoutAttributesForElementsInRect:方法返回的陣列時,沒有使用該陣列的拷貝物件,而是直接使用了該陣列。解決辦法對該陣列進行拷貝,並且是深拷貝。
- (NSArray *)deepCopyWithArray:(NSArray *)arr {
NSMutableArray *arrM = [NSMutableArrayarray];
for (UICollectionViewLayoutAttributes *attr in arr) {
[arrM addObject:[attr copy]];
}
return arrM;
}
@end
//
// ViewController.m
// HorizontalScale
//
// Created by zmx on 16/3/15.
// Copyright © 2016年 zmx. All rights reserved.
//
#import "ViewController.h"
#import "CollectionViewFlowLayout.h"
#import "Cell.h"
static NSString *identifier = @"c";
@interface ViewController () <UICollectionViewDataSource, UICollectionViewDelegate>
@property (weak, nonatomic) IBOutletUICollectionView *collectionView;
@property (weak, nonatomic) IBOutletCollectionViewFlowLayout *layout;
@end
@implementation ViewController
- (void)viewDidLoad {
[superviewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self.collectionViewregisterNib:[UINibnibWithNibName:@"Cell"bundle:nil] forCellWithReuseIdentifier:identifier];
}
- (void)viewDidLayoutSubviews {
[superviewDidLayoutSubviews];
self.layout.itemSize = CGSizeMake(100, 100);
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return 20;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
Cell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifierforIndexPath:indexPath];
return cell;
}
@end