UICollectionViewLayout的略以(简单瀑布流)UICollectionView的扩大。

by admin on 2018年10月5日

对此要采取到列表的页面,一般是采取UITableView或者是UICollectionView来落实。一直以来还是直接使用UICollectionViewFlowLayout,基本都能实现需求功能,但是对一直采用UICollectionViewLayout来自定义view的layout没怎么用了,这里翻了那个多材料自己写了demo,仅供日后参考了。
参考资料地址:
http://blog.csdn.net/majiakun1/article/details/17204921
http://www.cnblogs.com/wangyingblock/p/5627448.html

UICollectionView的结构回顾

UICollectionViewLayoutAttrubutes

一个颇重大的接近重点记录了cells,supplementaryViews,decorationviews的岗位,size,透明度,层级等

  • @property (nonatomic) CGRect frame; frame信息
  • @property (nonatomic) CGPoint center; 中心点
  • @property (nonatomic) CGSize size;大小
  • @property (nonatomic) CATransform3D transform3D;
  • @property (nonatomic) CGRect bounds NS_AVAILABLE_IOS(7_0);
  • @property (nonatomic) CGAffineTransform transform
    NS_AVAILABLE_IOS(7_0);
  • @property (nonatomic) CGFloat alpha;透明度
  • @property (nonatomic) NSInteger zIndex; // default is 0 层级
  • @property (nonatomic, getter=isHidden) BOOL hidden; // As an
    optimization, UICollectionView might not create a view for items
    whose hidden attribute is YES
  • @property (nonatomic, strong) NSIndexPath *indexPath;位置
  • @property (nonatomic, readonly) UICollectionElementCategory
    representedElementCategory;
  • @property (nonatomic, readonly, nullable) NSString
    *representedElementKind; 响应类型(区分cell,supple,decaration)
    那当UICollectionView获取布局之下会透过走访每个位置的部件通过该attribute来打探该布局信息

先是想起一下Collection View的三结合,我们能够看的发生三只有:

自定义一个UICollectionViewLayout

承自UICollectionViewLayout类,然后一般用重载下列方式:

  • -(void)prepareLayout;

  • 历次要布局上都见面自行调用,可以当这里修改部分必要之layout的布局以及始发需要之参数等

  • -(CGSize)collectionViewContentSize;

  • 定义UIcollectionView的ContentSize,内容大小

  • -(NSArray<UICollectionViewLayoutAttributes *>
    *)layoutAttributesForElementsInRect:(CGRect)rect;

  • 回可见区域rect内的富有因素的布局信息

  • 返回包含attributes的数组

  • -(UICollectionViewLayoutAttributes
    *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath;

  • 概念每个indexpath的item的布局信息

  • 相应的还有定义supplement以及decoration的艺术 这里就是未以展开列举

  • -(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds;

  • 当边界发生改变时,是否应该刷新布局。如果YES则以边界变化(一般是scroll到另外地方)时,将还计算需要之布局信息。

    demo

demo地址

Simulator Screen Shot 2016年10月13日 上午10.52.12.png

动用了相同组图与一个json文件(如果上加过后发现解析为空,在target
->Build Phase – >copy Bundle Resource添加需要之json文件)
正在减肥用之都是减肥励志的哄

Cells

PickModel

动及的model
.h

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@interface PicModel : NSObject
@property(nonatomic,strong) NSString *picPath;//图像
@property(nonatomic,strong) NSString *picDetail;//详细内容
@property(nonatomic,assign) CGFloat rowHeight;//行高

+(instancetype)initWithDic:(NSDictionary*)dic;
-(instancetype)initWithDic:(NSDictionary*)dic;

@end

.m
通过detail计算高度,计算所在item的惊人,这里图片的可观直接约束限制很了,可以变动吧遵循比例计算相当于。

#import "PicModel.h"

@implementation PicModel

+(instancetype)initWithDic:(NSDictionary*)dic{

    PicModel *model = [self alloc];
    return [model initWithDic:dic];
}

-(instancetype)initWithDic:(NSDictionary*)dic{

    if (self = [super init]) {
        self.picPath = dic[@"path"];
        self.picDetail = dic[@"detail"];

        CGFloat width = ([UIScreen mainScreen].bounds.size.width -(MAXCOUNT - 1) * 10)/MAXCOUNT;
        CGSize size = [dic[@"detail"] boundingRectWithSize:CGSizeMake(([UIScreen mainScreen].bounds.size.width -(MAXCOUNT - 1) * 10)/MAXCOUNT, MAXFLOAT) options:NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:15]} context:nil].size;
        self.rowHeight = size.height + 59 *width / 100 ;
    }
    return self;
}
@end

经改定义的列数

Pch文件.png

Supplementary Views 追加视图 (类似Header或者Footer)

ViewController

.m文件

#import "BaseViewController.h"
#import "PicModel.h"
#import "PureLayout.h"
#import "PureCollectionViewCell.h"

@interface BaseViewController ()<UICollectionViewDelegate,UICollectionViewDataSource>
@property(nonatomic,strong) UICollectionView *mainCollectionView;
@property(nonatomic,strong) NSMutableArray *dataArray;//数据源数组
@end

@implementation BaseViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.

    self.dataArray = [NSMutableArray array];
    //解析geojson文件
    NSString *jsonPath = [[NSBundle mainBundle] pathForResource:@"Detail" ofType:@"geojson"];
    NSArray *detailArr = [[NSJSONSerialization JSONObjectWithData:[NSData dataWithContentsOfFile:jsonPath] options:NSJSONReadingMutableContainers error:nil] objectForKey:@"data"
    ];

    //处理model数据
    for (int i =0; i<12; i++) {
        NSString *path = [NSString stringWithFormat:@"%d.jpg",i];
        PicModel *model = [PicModel initWithDic:[NSDictionary dictionaryWithObjectsAndKeys:path,@"path",detailArr[i],@"detail", nil]];
        [self.dataArray addObject:model];
    }

    [self definationMainCollectionView];

    //添加MJRefreshFooter 添加数据
    __weak typeof(self)weakSelf = self;
    self.mainCollectionView.mj_footer = [MJRefreshAutoNormalFooter footerWithRefreshingBlock:^{

        for (int i =0; i<12; i++) {
            NSString *path = [NSString stringWithFormat:@"%d.jpg",i];
            PicModel *model = [PicModel initWithDic:[NSDictionary dictionaryWithObjectsAndKeys:path,@"path",detailArr[i],@"detail", nil]];
            [weakSelf.dataArray addObject:model];
        }
        [weakSelf.mainCollectionView reloadData];
        [weakSelf.mainCollectionView.mj_footer endRefreshing];
    }];
}

/**
 *  设置相关UICollectionView信息
 */
-(void)definationMainCollectionView{

    PureLayout *layout = [[PureLayout alloc] init];
    layout.dataArray = self.dataArray;

    self.mainCollectionView = [[UICollectionView alloc] initWithFrame:[UIScreen mainScreen].bounds collectionViewLayout:layout];
    [self.mainCollectionView registerNib:[UINib nibWithNibName:@"PureCollectionViewCell" bundle:nil] forCellWithReuseIdentifier:@"pureCell"];
    self.mainCollectionView.delegate = self;
    self.mainCollectionView.dataSource = self;
    self.mainCollectionView.backgroundColor = [UIColor whiteColor];
    [self.view addSubview:self.mainCollectionView];
}

#pragma mark - UICollectionViewDataSource
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{

    return 1;
}

-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{

   return  self.dataArray.count;
}

-(UICollectionViewCell*)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{

    PureCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"pureCell" forIndexPath:indexPath];
    PicModel *model = self.dataArray[indexPath.row];
    cell.model = model;
    return cell;
}

Decoration Views 装饰视图 (用作背景展示)

PureLayout

.h文件,这里大概的一直传送了数据源

@interface PureLayout : UICollectionViewLayout

@property(nonatomic,strong)NSArray *dataArray;//数据源
@property(nonatomic,assign) NSInteger maxCount;//列数
@end

.m文件 定义需要出示的列数,水平 垂直距离等骨干信息

#import "PureLayout.h"
#import "PicModel.h"

static CGFloat horizonalSpace = 10;//水平间隔
static CGFloat verticalSpace = 15;//垂直间隔

@interface PureLayout ()
@property(nonatomic,strong) NSMutableArray *offSets;//用于存储不同列的MAXY信息
@end

@implementation PureLayout

-(void)prepareLayout{

    _maxCount = MAXCOUNT;
}

依据需要出示的列数,使用数组分别记录每行所在列item的frame.origin.y,进行对照,设置UICollectionView的contentsize

-(CGSize)collectionViewContentSize{

    CGFloat width = [UIScreen mainScreen].bounds.size.width;
    CGFloat height = 0.0;

   _offSets = [NSMutableArray array];

    for (int i =0; i<_maxCount; i++) {
        [_offSets addObject:@0];
    }

    for (int i = 0; i<self.dataArray.count; i++) {
        NSInteger col = i % _maxCount;
        PicModel *model = self.dataArray[i];

        CGFloat offSetY ;
        offSetY = [_offSets[col] floatValue] + model.rowHeight + verticalSpace;
        _offSets[col] = @(offSetY);
        height = MAX(height, offSetY);
    }

    if (height < [UIScreen mainScreen].bounds.size.height) {
        height = [UIScreen mainScreen].bounds.size.height;
    }
    return CGSizeMake(width, height);
}

返回可见Rect内的元素的attributes信息

-(NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect{

    NSMutableArray * attributes = [NSMutableArray array];
    for (int i =0 ; i<self.dataArray.count; i++) {
        UICollectionViewLayoutAttributes *attribute = [self layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0]];
        [attributes addObject:attribute];
    }
    return attributes;
}

本着两样的indexpath的items设置attributes信息

-(UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath{

    UICollectionViewLayoutAttributes *attribute = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
    PicModel *model = self.dataArray[indexPath.row];
    CGFloat itemWidth = ([UIScreen mainScreen].bounds.size.width - (MAXCOUNT - 1) * 10)/_maxCount;
    attribute.size = CGSizeMake(itemWidth, model.rowHeight);
    CGFloat itemY = 0.0;
    CGFloat itemX = 0.0;

    NSInteger col = indexPath.row % _maxCount;
    itemX = (([UIScreen mainScreen].bounds.size.width - (MAXCOUNT - 1) * 10)/_maxCount + horizonalSpace)* col;
    if (indexPath.row <_maxCount) {
        itemY = 0.0;
    }else{
        UICollectionViewLayoutAttributes *otherAttribute = [self layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForRow:indexPath.row - _maxCount inSection:0]];
        itemY = CGRectGetMaxY(otherAttribute.frame) + verticalSpace;
    }

    attribute.frame = CGRectMake(itemX, itemY, itemWidth,  model.rowHeight);
    return attribute;
}

终极加加上该办法,边界改变是重布局

-(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds{

    return YES;
}

单独是一个简便的额瀑布流demo,还有蛮多地方要优化,这里只有写下有些基本思路。

法定给出的简单只demo很有攻价值,CircleLayout以及LinLayout,在自之前的受闹的参阅链接里面还是得一直下载的,对于同篇章被的CircleLayout用法,insert和delete方法已于appearing和disappearing取代了,参考的githubdemo被自己fork了一样卖,可以开展下载上
https://github.com/w467364316/CircleLayout.git

要是于外表下,由个别独面针对UICollectionView进行支持。其中之一以及tableView一样,即提供数据的
UICollectionViewDataSource以及处理用户交互的UICollectionViewDelegate。另一方面,对于cell的
样式和组织章程,由于collectionView比tableView要复杂得几近,因此无如约类似于tableView的style的不二法门来定义,而
是专门采用了一个近乎来对collectionView的布局及行为进行描述,这就是是UICollectionViewLayout。

这次的笔记将把要放在UICollectionViewLayout上,因为这不只是collectionView和tableView的最重要求的界别,也是全部UICollectionView的精华所在。

如果对UICollectionView的骨干成因素和应用方法还免亮的话,可以移动到自己事先的同篇笔记:Session笔记——205
Introducing Collection
Views着进行局部打听。

UICollectionViewLayoutAttributes

UICollectionViewLayoutAttributes是一个异常关键之接近,先来探视property列表:

@property (nonatomic) CGRect frame

@property (nonatomic) CGPoint center

@property (nonatomic) CGSize size

@property (nonatomic) CATransform3D transform3D

@property (nonatomic) CGFloat alpha

@property (nonatomic) NSInteger zIndex

@property (nonatomic, getter=isHidden) BOOL hidden

足见见,UICollectionViewLayoutAttributes的实例中包含了如边框,中心点,大小,形状,透明度,层次关系和是否隐藏
等信息。和DataSource的一言一行好近乎,当UICollectionView在获取布局时拿本着各一个indexPath的构件(包括cell,
追加视图和装潢视图),向那达成之UICollectionViewLayout实例询问该构件的布局信息(在斯局面上说之口舌,实现一个
UICollectionViewLayout的时候,其实非常像是zap一个delegate,之后的例子中见面特别显眼地视),这个布局信息,就以
UICollectionViewLayoutAttributes的实例的主意吃出。

于定义之UICollectionViewLayout

UICollectionViewLayout的功力为于UICollectionView提供布局信息,不仅包括cell的布局信息,也囊括多视图和
装饰视图的布局信息。实现一个自定义layout的例行做法是继承UICollectionViewLayout类,然后重载下列方法:

-(CGSize)collectionViewContentSize

返collectionView的内容之尺寸

-(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect

回rect中的富有的元素的布局属性

返回的凡含UICollectionViewLayoutAttributes的NSArray

UICollectionViewLayoutAttributes可以是cell,追加视图或装饰视图的音讯,通过不同之
UICollectionViewLayoutAttributes初始化方法可落不同品种的
UICollectionViewLayoutAttributes:

layoutAttributesForCellWithIndexPath:

layoutAttributesForSupplementaryViewOfKind:withIndexPath:

layoutAttributesForDecorationViewOfKind:withIndexPath:

-(UICollectionViewLayoutAttributes)layoutAttributesForItemAtIndexPath:(NSIndexPath)indexPath

回到对应于indexPath的职的cell的布局属性

-(UICollectionViewLayoutAttributes)layoutAttributesForSupplementaryViewOfKind:(NSString)kind
atIndexPath:(NSIndexPath *)indexPath

归来对应为indexPath的职务的增多视图的布局属性,如果没有长视图可免重载

-(UICollectionViewLayoutAttributes *
)layoutAttributesForDecorationViewOfKind:(NSString)decorationViewKind
atIndexPath:(NSIndexPath)indexPath

回对应于indexPath的岗位的装潢视图的布局属性,如果无装修视图可免重载

-(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds

当边界有变动时,是否应刷新布局。如果YES则于疆变化(一般是scroll到任何地方)时,将再也计算需要之布局信息。

另外要了解之是,在初始化一个UICollectionViewLayout实例后,会来同样多元准备方法给活动调用,以担保layout实例的科学。

第一,-(void)prepareLayout将被调用,默认下该方式什么没做,但是于融洽之子类实现着,一般在该办法被设定有必备之layout的布局以及开需要的参数等。

以后,-(CGSize)
collectionViewContentSize将让调用,以确定collection应该占据的尺码。注意这里的尺寸未是乘可视部分的尺码,而应该
是所有情节所占用的尺寸。collectionView的面目是一个scrollView,因此要之尺寸来布局滚动行为。

接下来-(NSArray
*)layoutAttributesForElementsInRect:(CGRect)rect被调用,这个没什么值得多说之。初始的layout
的外观将由该法返回的UICollectionViewLayoutAttributes来支配。

此外,在用更新layout时,需要为当下layout发送
-invalidateLayout,该信息会这赶回,并且预约在产一个loop的时段刷新时layout,这或多或少和UIView的
setNeedsLayout方法十分近似。在-invalidateLayout后的生一个collectionView的刷新loop中,又见面由
prepareLayout开始,依次再调用-collectionViewContentSize和
-layoutAttributesForElementsInRect来变化更新后底布局。

Demo

说了那么多,其实还是Demo最能缓解问题。Apple官方给了一个flow
layout和一个circle
layout的例证,都异常经典,需要之校友可以起此处下载。

LineLayout——对于个别UICollectionViewLayoutAttributes的调整

先押LineLayout,它继续了UICollectionViewFlowLayout这个Apple提供的基本的布局。它根本实现了单行布局,自动对旅到网格以及时网格cell放大三独特征。如图:

先看LineLayout的init方法:

1234567891011

-(id)init{self=[superinit];if(self){self.itemSize=CGSizeMake(ITEM_SIZE,ITEM_SIZE);self.scrollDirection=UICollectionViewScrollDirectionHorizontal;self.sectionInset=UIEdgeInsetsMake(200,0.0,200,0.0);self.minimumLineSpacing=50.0;}returnself;}

self.sectionInset = UIEdgeInsetsMake(200, 0.0, 200, 0.0);
确定了缩进,此处为上以及江湖各缩进200个point。由于cell的size已经定义了邪200×200,因此屏幕及于缩进后即便单单出平等免去item的空
间了。

self.minimumLineSpacing = 50.0;
这个定义了每个item在档次方向上之最好小间隔。

UICollectionViewFlowLayout是Apple为咱准备的开袋即食的成布局,因此前提到的几个必须重载的点子吃得我们担心的
很少,即使完全不重载它们,现在吧足以获取一个不错的线状一行的gridview了。而我们的LineLayout通过重载父类方法后,可以兑现有新特
性,比如这里的动对旅到网格以及时网格cell放坏。

电动对共同到网格

1234567891011121314151617

-(CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffsetwithScrollingVelocity:(CGPoint)velocity{//proposedContentOffset是没针对联合到网格时当当告一段落的职CGFloatoffsetAdjustment=MAXFLOAT;CGFloathorizontalCenter=proposedContentOffset.x+(CGRectGetWidth(self.collectionView.bounds)/2.0);CGRecttargetRect=CGRectMake(proposedContentOffset.x,0.0,self.collectionView.bounds.size.width,self.collectionView.bounds.size.height);NSArray*array=[superlayoutAttributesForElementsInRect:targetRect];//对时屏幕中之UICollectionViewLayoutAttributes逐个同屏幕中心进行比,找来最为接近中心的一个for(UICollectionViewLayoutAttributes*layoutAttributesinarray){CGFloatitemHorizontalCenter=layoutAttributes.center.x;if(ABS(itemHorizontalCenter-horizontalCenter)<ABS(offsetAdjustment)){offsetAdjustment=itemHorizontalCenter-horizontalCenter;}}returnCGPointMake(proposedContentOffset.x+offsetAdjustment,proposedContentOffset.y);}

当前item放大

1234567891011121314151617181920

-(NSArray*)layoutAttributesForElementsInRect:(CGRect)rect{NSArray*array=[superlayoutAttributesForElementsInRect:rect];CGRectvisibleRect;visibleRect.origin=self.collectionView.contentOffset;visibleRect.size=self.collectionView.bounds.size;for(UICollectionViewLayoutAttributes*attributesinarray){if(CGRectIntersectsRect(attributes.frame,rect)){CGFloatdistance=CGRectGetMidX(visibleRect)-attributes.center.x;CGFloatnormalizedDistance=distance/ACTIVE_DISTANCE;if(ABS(distance)<ACTIVE_DISTANCE){CGFloatzoom=1+ZOOM_FACTOR*(1-ABS(normalizedDistance));attributes.transform3D=CATransform3DMakeScale(zoom,zoom,1.0);attributes.zIndex=1;}}}returnarray;}

于个别UICollectionViewLayoutAttributes进行调整,以高达满足设计要求是UICollectionView使用受到的均等
种思路。在依据职务提供不同layout属性的当儿,需要记得吃-shouldInvalidateLayoutForBoundsChange:返回
YES,这样当边界改变之时,-invalidateLayout会自动为发送,才能够为layout得到刷新。

CircleLayout——完全从定义的Layout,添加删减item,以及手势识别

CircleLayout的事例稍微复杂一些,cell分布在团上,点击cell的话会将该打collectionView中改换有,点击空白处会加入一个cell,加入与移出都产生动画效果。

立在以前的话语量够写一阵子了,而受益于UICollectionView,基本就需要100来行代码就足以搞定这通,非常cheap。通过CircleLayout的实现,可以完全地盼从定义的layout的编撰流程,非常具有学习及借鉴之含义。

CircleLayout

首先,布局准备被定义了有的事后计算所欲以的参数。

123456789

-(void)prepareLayout{//和init相似,必须call
super的prepareLayout以保初始化正确[superprepareLayout];CGSizesize=self.collectionView.frame.size;_cellCount=[[selfcollectionView]numberOfItemsInSection:0];_center=CGPointMake(size.width/2.0,size.height/2.0);_radius=MIN(size.width,size.height)/2.5;}

实则对一个size不变的collectionView来说,除了_cellCount之外的核心和半径的概念也堪摒弃到init里去开,但是明显以
prepareLayout里做的语有更特别的油滑。因为老是重复给出layout时犹见面调用prepareLayout,这样以之后要是起
collectionView大小变化之求时为堪活动适应变化。

然后,按照UICollectionViewLayout子类的要求,重载了所需要之计:

123456789101112131415161718192021222324252627

//整个collectionView的内容大小就collectionView的尺寸(没有滚动)-(CGSize)collectionViewContentSize{return[selfcollectionView].frame.size;}//通过所当的indexPath确定位置。-(UICollectionViewLayoutAttributes*)layoutAttributesForItemAtIndexPath:(NSIndexPath*)path{UICollectionViewLayoutAttributes*attributes=[UICollectionViewLayoutAttributeslayoutAttributesForCellWithIndexPath:path];//生成空白的attributes对象,其中只记录了品种是cell以及相应的职务是indexPath//配置attributes到周周上attributes.size=CGSizeMake(ITEM_SIZE,ITEM_SIZE);attributes.center=CGPointMake(_center.x+_radius*cosf(2*path.item*M_PI/_cellCount),_center.y+_radius*sinf(2*path.item*M_PI/_cellCount));returnattributes;}//用来当同一方始于有同样效UICollectionViewLayoutAttributes-(NSArray*)layoutAttributesForElementsInRect:(CGRect)rect{NSMutableArray*attributes=[NSMutableArrayarray];for(NSIntegeri=0;i<self.cellCount;i++){//这里用了-layoutAttributesForItemAtIndexPath:来取得attributesNSIndexPath*indexPath=[NSIndexPathindexPathForItem:iinSection:0];[attributesaddObject:[selflayoutAttributesForItemAtIndexPath:indexPath]];}returnattributes;}

兹早已赢得了一个circle
layout。为了落实cell的丰富跟去,需要为collectionView加上手势识别,这个大简单,在ViewController中:

12

UITapGestureRecognizer*tapRecognizer=[[UITapGestureRecognizeralloc]initWithTarget:selfaction:@selector(handleTapGesture:)];[self.collectionViewaddGestureRecognizer:tapRecognizer];

相应的拍卖方法handleTapGesture:为

1234567891011121314151617

-(void)handleTapGesture:(UITapGestureRecognizer*)sender{if(sender.state==UIGestureRecognizerStateEnded){CGPointinitialPinchPoint=[senderlocationInView:self.collectionView];NSIndexPath*tappedCellPath=[self.collectionViewindexPathForItemAtPoint:initialPinchPoint];//获取点击处的cell的indexPathif(tappedCellPath!=nil){//点击处没有cellself.cellCount=self.cellCount-1;[self.collectionViewperformBatchUpdates:^{[self.collectionViewdeleteItemsAtIndexPaths:[NSArrayarrayWithObject:tappedCellPath]];}completion:nil];}else{self.cellCount=self.cellCount+1;[self.collectionViewperformBatchUpdates:^{[self.collectionViewinsertItemsAtIndexPaths:[NSArrayarrayWithObject:[NSIndexPathindexPathForItem:0inSection:0]]];}completion:nil];}}}

performBatchUpdates:completion:
再次显示了block的雄强的一面..之法可就此来针对collectionView中的因素进行批量之插入,删除,移动等操作,同时将触发
collectionView所对应的layout的应和之卡通片。相应的卡通片由layout中的下列四单艺术来定义:

initialLayoutAttributesForAppearingItemAtIndexPath:

initialLayoutAttributesForAppearingDecorationElementOfKind:atIndexPath:

finalLayoutAttributesForDisappearingItemAtIndexPath:

finalLayoutAttributesForDisappearingDecorationElementOfKind:atIndexPath:

重新凑巧:正式版中API发生了变动(而且不止一次变化
initialLayoutAttributesForInsertedItemAtIndexPath:在规范版中都给丢掉。现在当insert或者
delete之前,prepareForCollectionViewUpdates:会受调用,可以使用这个方法来就长/删除的布局。关于更多就方
面的情及新的演示demo,可以参见立马首博文(需要翻墙)。新的以身作则demo在Github上吗生,链接

在CircleLayout中,实现了cell的动画。

123456789101112131415161718

//插入前,cell在圆心位置,全透明-(UICollectionViewLayoutAttributes*)initialLayoutAttributesForInsertedItemAtIndexPath:(NSIndexPath*)itemIndexPath{UICollectionViewLayoutAttributes*attributes=[selflayoutAttributesForItemAtIndexPath:itemIndexPath];attributes.alpha=0.0;attributes.center=CGPointMake(_center.x,_center.y);returnattributes;}//删除时,cell在圆心位置,全透明,且只有本的1/10大-(UICollectionViewLayoutAttributes*)finalLayoutAttributesForDeletedItemAtIndexPath:(NSIndexPath*)itemIndexPath{UICollectionViewLayoutAttributes*attributes=[selflayoutAttributesForItemAtIndexPath:itemIndexPath];attributes.alpha=0.0;attributes.center=CGPointMake(_center.x,_center.y);attributes.transform3D=CATransform3DMakeScale(0.1,0.1,1.0);returnattributes;}

在插入或删除时,将独家因插队入前同去后的attributes和普通状态下之attributes为法,进行UIView的动画过渡。而立即整个并没过剩代码要描绘,几乎是free的,感谢苹果…

布局中的切换

偶尔可能需要不同之布局,Apple也供了造福的布局里面切换的点子。直接改动collectionView的
collectionViewLayout属性可以及时切换布局。而若经过setCollectionViewLayout:animated:,则可
以以切换布局的而,使用动画片来连接。对于每一个cell,都将发对应的UIView动画进行相应,又是一个近乎free的特色。

于我自己来说,UICollectionView可能是自身转发iOS 6
SDK的极端具吸引力的特色有,因为UIKit团队的全力以及CoreAnimation的秋,使得创建一个良优雅的UI变的愈加简单了。可以断言
说UICollectionView在其后之iOS开发被,一定会成为与UITableView一样的强有力以及无限常用的类有。在iOS
6还无正式上市前,先对该性状开展部分读书,以期尽快能利用初特点来简化开发流程,可以算得非常值得的。

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图