UICollectionViewFlowLayout自定义(圆圈)

我是看他人的博客复写的一份demo,不足之处多多指教,不多说,先贴代码!

1、创建了一个 CircleLayout 继承UICollectionViewFlowLayout 类。

CircleLayout.h文件代码

#import <UIKit/UIKit.h>


@interface CircleLayout : UICollectionViewFlowLayout

//中心

@property (nonatomic, assign) CGPoint center;

//半径

@property (nonatomic, assign) CGFloat radius;

//cell数量

@property (nonatomic, assign) NSInteger cellCount;

@end


CircleLayout.m文件代码

#import "CircleLayout.h"


#define ITEM_SIZE (50.0f)


@interface CircleLayout ()


@property (nonatomic, strong) NSMutableArray *deleteIndexPaths;

@property (nonatomic, strong) NSMutableArray *insertIndexPaths;


@end


@implementation CircleLayout


//(第一步)布局准备中定义了一些之后计算所需要用到的参数。

//其实,_center _radius 也可以放在 init 方法里面,但是 prepareLayout 具有更大的灵活性,因为每次重新给出一个layout时都会掉用prepareLayout,这样的如果有collectionView的大小变化需求时会自动适应变化。

-(void)prepareLayout{


    //init相似,必须call superprepareLayout以保证初始化正确

    [super prepareLayout];

    

    CGSize size = self.collectionView.frame.size;

    

    //水平移动,但是不知道为什么不能滚动

    self.scrollDirection = UICollectionViewScrollDirectionHorizontal;

    

    _cellCount = [[self collectionView] numberOfItemsInSection:0];

    

    //控制cell所在圆圈的中心点坐标

    _center = CGPointMake(size.width / 2.0, size.height / 1.5);

    

    //控制cell所在的圆圈的大小

    _radius = MIN(size.width, size.height) / 4;

}


//(第二步)按照UICollectionViewLayout子类的要求,重载了所需要的方法:

//整个collectionView的内容大小就是collectionView的大小(没有滚动)

-(CGSize) collectionViewContentSize

{


    return [self collectionView].frame.size;

}


//(第三步)通过所在的indexPath确定位置

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

{


    //生成空白的attributes对象,其中只记录了类型是cell以及对应的位置是indexPath

    UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];

    

    //配置attributes到圆周上

    attributes.size = CGSizeMake(ITEM_SIZE, ITEM_SIZE);

    

    attributes.center = CGPointMake(_center.x + _radius * cosf(2 * indexPath.item * M_PI / _cellCount), _center.y + _radius * sinf(2 * indexPath.item * M_PI / _cellCount));

    

    return attributes;

}


//(第四步)用来在一开始给出一套UICollectionViewLayoutAttributes

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

{


    NSMutableArray *attributes = [NSMutableArray array];

    for(NSInteger i = 0; i < _cellCount; i++)

    {

        NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];

        [attributes addObject:[self layoutAttributesForItemAtIndexPath:indexPath]];

    }

    return attributes;

}


//插入前,cell在圆心位置,全透明(不过当前方法已经被弃用,用下面的prepareForCollectionViewUpdates方法)

#if 0

- (UICollectionViewLayoutAttributes *)initialLayoutAttributesForInsertedItemAtIndexPath:(NSIndexPath *)itemIndexPath

{

    UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForItemAtIndexPath:itemIndexPath];

    attributes.alpha = 0.0;

    attributes.center = CGPointMake(_center.x, _center.y);

    

    return attributes;

}

#endif


//更新UICollectionViewCell调用的方法(删除、插入、移动...

-(void)prepareForCollectionViewUpdates:(NSArray<UICollectionViewUpdateItem *> *)updateItems

{


    [super prepareForCollectionViewUpdates:updateItems];

    

    self.deleteIndexPaths = [NSMutableArray array];

    self.insertIndexPaths = [NSMutableArray array];

    

    for(UICollectionViewUpdateItem *update in updateItems){

        //删除事件

        if (update.updateAction == UICollectionUpdateActionDelete) {

            

            [self.deleteIndexPaths addObject:update.indexPathBeforeUpdate];

        }

        //插入事件

        else if (update.updateAction == UICollectionUpdateActionInsert){

            

            [self.insertIndexPaths addObject:update.indexPathAfterUpdate];

        }

    }

}


-(void)finalizeCollectionViewUpdates

{

    [super finalizeCollectionViewUpdates];


    self.deleteIndexPaths = nil;

    self.insertIndexPaths = nil;

}


//插入

-(UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingItemAtIndexPath:(NSIndexPath *)itemIndexPath

{

    UICollectionViewLayoutAttributes *attributes = [super initialLayoutAttributesForAppearingItemAtIndexPath:itemIndexPath];

    

    if ([self.insertIndexPaths containsObject:itemIndexPath]) {

        if (!attributes) {

            attributes = [self layoutAttributesForItemAtIndexPath:itemIndexPath];

            

            attributes.alpha = 0.0;

            

            attributes.center = CGPointMake(_center.x, _center.y);

            

        }

    }

    

    return attributes;

}


//删除

- (UICollectionViewLayoutAttributes *)finalLayoutAttributesForDisappearingItemAtIndexPath:(NSIndexPath *)itemIndexPath

{


    UICollectionViewLayoutAttributes *attributes = [super finalLayoutAttributesForDisappearingItemAtIndexPath:itemIndexPath];

    

    if ([self.deleteIndexPaths containsObject:itemIndexPath])

    {

        

        if (!attributes)

            attributes = [self layoutAttributesForItemAtIndexPath:itemIndexPath];

        

            attributes.alpha = 0.0;

            attributes.center = CGPointMake(_center.x, _center.y);

            //消失的一个动画效果

            attributes.transform3D = CATransform3DMakeScale(0.1, 0.1, 1.0);

    }

    

    return attributes;

}


@end


写了一个Cell类,继承UICollectionViewCell类

cell.h文件代码

#import <UIKit/UIKit.h>

@interface Cell : UICollectionViewCell


@property (nonatomic, strong) UILabel *label;


@end


cell.m文件代码

#import "Cell.h"


@implementation Cell



-(instancetype)initWithFrame:(CGRect)frame{

    self = [super initWithFrame:frame];

    if (self) {

        

        UIView *view = [[UIView alloc] initWithFrame:self.bounds];

        view.backgroundColor = [UIColor purpleColor];

        view.layer.cornerRadius = self.bounds.size.width / 2;

        [self.contentView addSubview:view];

        

        self.label = [[UILabel alloc] initWithFrame:CGRectMake(view.center.x - 10, view.center.y - 10, 20, 20)];

      

        self.label.textAlignment = NSTextAlignmentCenter;

        self.label.textColor = [UIColor whiteColor];

        self.label.backgroundColor = [UIColor clearColor];

        [view addSubview:self.label];

        

    }

    return self;

}



@end





在viewController使用时的情况。
viewController.m文件代码


#import "ViewController.h"

#import "CircleLayout.h"

#import "Cell.h"

@interface ViewController ()<UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout>


@property (nonatomic, strong) UICollectionView *collectionView;


@property (assign, nonatomic) NSInteger cellCount;


@end


@implementation ViewController


- (void)viewDidLoad {

    [super viewDidLoad];

    // Do any additional setup after loading the view, typically from a nib.

    

    self.view.backgroundColor = [UIColor whiteColor];

    

    CircleLayout *layout = [[CircleLayout alloc] init];

    

    self.cellCount = 5;

    

    self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 200, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height - 400) collectionViewLayout:layout];

    self.collectionView.backgroundColor = [UIColor grayColor];

    self.collectionView.dataSource = self;

    self.collectionView.delegate =self;

    self.collectionView.userInteractionEnabled = YES;

    self.collectionView.scrollEnabled = YES;

    [self.collectionView registerClass:[Cell class] forCellWithReuseIdentifier:@"my_cell_id"];

    [self.view addSubview:self.collectionView];

    

    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction:)];

    [self.collectionView addGestureRecognizer:tap];

}


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

{

    return self.cellCount;

}


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

{

    Cell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"my_cell_id" forIndexPath:indexPath];

    cell.label.text = [NSString stringWithFormat:@"%ld", indexPath.row];

   

    return cell;

}


-(void)tapAction:(UITapGestureRecognizer *)sender

{

    if (sender.state == UIGestureRecognizerStateEnded)

    {

        CGPoint initialPinchPoint = [sender locationInView:self.collectionView];

        NSIndexPath* tappedCellPath = [self.collectionView indexPathForItemAtPoint:initialPinchPoint];

        if (tappedCellPath!=nil)

        {

            self.cellCount = self.cellCount - 1;

            [self.collectionView performBatchUpdates:^{

                [self.collectionView deleteItemsAtIndexPaths:[NSArray arrayWithObject:tappedCellPath]];

                

            } completion:nil];

        }

        else

        {

            self.cellCount = self.cellCount + 1;

            [self.collectionView performBatchUpdates:^{

                [self.collectionView insertItemsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForItem:0 inSection:0]]];

            } completion:nil];

        }

    }

}


- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}


@end




效果就是这样,这里贴上我看到的博客地址,有兴趣的可以去瞅瞅!

http://blog.csdn.net/majiakun1/article/details/17204921



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值