1. 程式人生 > >UICollectionViewCell水平縮放,中間大兩邊小效果的實現

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

.bounds.size.width;

        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