iOS開發,ios開發教程
Model cell
@interface ImageCell : UICollectionViewCell@property (nonatomic, copy) NSString *image;@end
@interface ImageCell()@property (weak, nonatomic) IBOutlet UIImageView *imageView;@end@implementation ImageCell- (void)awakeFromNib { self.imageView.layer.borderWidth = 3; self.imageView.layer.borderColor = [UIColor whiteColor].CGColor; self.imageView.layer.cornerRadius = 3; self.imageView.clipsToBounds = YES;}- (void)setImage:(NSString *)image{ _image = [image copy]; self.imageView.image = [UIImage imageNamed:image];}@end
LineLayout
#import "LineLayout.h"static const CGFloat ItemWH = 100;@implementation LineLayout- (instancetype)init{ if (self = [super init]) { } return self;}/** * 只要顯示的邊界發生改變就重新布局: 內部會重新調用prepareLayout和layoutAttributesForElementsInRect方法獲得所有cell的布局屬性 */- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds{ return YES;}/** * 用來設定collectionView停止滾動那一刻的位置 * * @param proposedContentOffset 原本collectionView停止滾動那一刻的位置 * @param velocity 捲動速度 */- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity{ // 1.計算出scrollView最後會停留的範圍 CGRect lastRect; lastRect.origin = proposedContentOffset; lastRect.size = self.collectionView.frame.size; // 計算螢幕最中間的x CGFloat centerX = proposedContentOffset.x + self.collectionView.frame.size.width * 0.5; // 2.取出這個範圍內的所有屬性 NSArray *array = [self layoutAttributesForElementsInRect:lastRect]; // 3.遍曆所有屬性 CGFloat adjustOffsetX = MAXFLOAT; for (UICollectionViewLayoutAttributes *attrs in array) { if (ABS(attrs.center.x - centerX) < ABS(adjustOffsetX)) { adjustOffsetX = attrs.center.x - centerX; } } return CGPointMake(proposedContentOffset.x + adjustOffsetX, proposedContentOffset.y);}/** * 一些初始化工作最好在這裡實現 */- (void)prepareLayout{ [super prepareLayout]; // 每個cell的尺寸 self.itemSize = CGSizeMake(ItemWH, ItemWH); CGFloat inset = (self.collectionView.frame.size.width - ItemWH) * 0.5; self.sectionInset = UIEdgeInsetsMake(0, inset, 0, inset); // 設定水平滾動 self.scrollDirection = UICollectionViewScrollDirectionHorizontal; self.minimumLineSpacing = ItemWH * 0.7; // 每一個cell(item)都有自己的UICollectionViewLayoutAttributes // 每一個indexPath都有自己的UICollectionViewLayoutAttributes}/** 有效距離:當item的中間x距離螢幕的中間x在ActiveDistance以內,才會開始放大, 其它情況都是縮小 */static CGFloat const ActiveDistance = 150;/** 縮放因素: 值越大, item就會越大 */static CGFloat const ScaleFactor = 0.6;- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect{ // 0.計算可見的矩形框 CGRect visiableRect; visiableRect.size = self.collectionView.frame.size; visiableRect.origin = self.collectionView.contentOffset; // 1.取得預設的cell的UICollectionViewLayoutAttributes NSArray *array = [super layoutAttributesForElementsInRect:rect]; // 計算螢幕最中間的x CGFloat centerX = self.collectionView.contentOffset.x + self.collectionView.frame.size.width * 0.5; // 2.遍曆所有的布局屬性 for (UICollectionViewLayoutAttributes *attrs in array) { // 如果不在螢幕上,直接跳過 if (!CGRectIntersectsRect(visiableRect, attrs.frame)) continue; // 每一個item的中點x CGFloat itemCenterX = attrs.center.x; // 差距越小, 縮放比例越大 // 根據跟螢幕最中間的距離計算縮放比例 CGFloat scale = 1 + ScaleFactor * (1 - (ABS(itemCenterX - centerX) / ActiveDistance)); attrs.transform = CGAffineTransformMakeScale(scale, scale); } return array;}@end
ViewController
#import "ViewController.h"#import "ImageCell.h"#import "LineLayout.h"@interface ViewController () <UICollectionViewDataSource, UICollectionViewDelegate>@property (nonatomic, strong) NSMutableArray *images;@property (nonatomic, weak) UICollectionView *collectionView;@end@implementation ViewControllerstatic NSString *const ID = @"image";- (NSMutableArray *)images{ if (!_images) { self.images = [[NSMutableArray alloc] init]; for (int i = 1; i<=20; i++) { [self.images addObject:[NSString stringWithFormat:@"%d", i]]; } } return _images;}- (void)viewDidLoad { [super viewDidLoad]; CGFloat w = self.view.frame.size.height; CGRect rect = CGRectMake(0, 0, w, 200); UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:rect collectionViewLayout:[[LineLayout alloc] init]]; collectionView.dataSource = self; collectionView.delegate = self; [collectionView registerNib:[UINib nibWithNibName:@"ImageCell" bundle:nil] forCellWithReuseIdentifier:ID]; [self.view addSubview:collectionView]; self.collectionView = collectionView; // collectionViewLayout : // UICollectionViewLayout // UICollectionViewFlowLayout}- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ if ([self.collectionView.collectionViewLayout isKindOfClass:[LineLayout class]]) { [self.collectionView setCollectionViewLayout:[[UICollectionViewFlowLayout alloc] init] animated:YES]; } else { [self.collectionView setCollectionViewLayout:[[LineLayout alloc] init] animated:YES]; }}#pragma mark - <UICollectionViewDataSource>- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{ return self.images.count;}- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{ ImageCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:ID forIndexPath:indexPath]; cell.image = self.images[indexPath.item]; return cell;}- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{ // 刪除模型資料 [self.images removeObjectAtIndex:indexPath.item]; // 刪UI(重新整理UI) [collectionView deleteItemsAtIndexPaths:@[indexPath]];}@end
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。