UICollectionView之自定义Layout

#import <UIKit/UIKit.h>

 

@interface WQViewController : UIViewController

- (id)initWithFrame:(CGRect)frame;

@end

#import "WQViewController.h"

#import "WQCollectionViewController.h"

#import "WQCollectionViewCircleLayout.h"

 

@interface WQViewController ()

 

@end

 

@implementation WQViewController

 

- (id)initWithFrame:(CGRect)frame {

    if (self == [super init]) {

        self.view.frame = frame;

        self.view.backgroundColor = [UIColor yellowColor];

    }

    return self;

}

 

- (void)viewDidLoad {

    [super viewDidLoad];

    

    WQCollectionViewCircleLayout *circleLayout = [[WQCollectionViewCircleLayout alloc] init];

    WQCollectionViewController *collectionVC = [[WQCollectionViewController alloc] initWithCollectionViewLayout:circleLayout];

    [self addChildViewController:collectionVC];

    [self.view addSubview:collectionVC.collectionView];

}

 

- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

 

@end

~~~~~~~~~~~~~~~~~~~~~~~

#import <UIKit/UIKit.h>

 

@interface WQCollectionViewController : UICollectionViewController

 

@end

#import "WQCollectionViewController.h"

#import "WQCollectionViewCircleLayout.h"

#import "WQCollectionViewCell.h"

 

@interface WQCollectionViewController ()

 

@property (assign, nonatomic) NSInteger     cellCount;

 

@end

 

@implementation WQCollectionViewController

 

static NSString * const reuseIdentifier = @"Cell";

 

- (void)viewDidLoad {

    [super viewDidLoad];

    _cellCount = 8;

    

    self.collectionView.frame = [UIScreen mainScreen].bounds;

    self.collectionView.backgroundColor = [UIColor whiteColor];

    

    [self.collectionView registerClass:[WQCollectionViewCell class] forCellWithReuseIdentifier:reuseIdentifier];

    

    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapGesture:)];

    [self.collectionView addGestureRecognizer:tapGesture];

}

#pragma mark - UITapGesture

 

- (void)handleTapGesture:(UITapGestureRecognizer *)sender {

    if (sender.state == UIGestureRecognizerStateEnded) {

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

        NSIndexPath *tapCellPath = [self.collectionView indexPathForItemAtPoint:initiailPinchPoint];

        if (tapCellPath != nil) {

            

            [self.collectionView performBatchUpdates:^{

                self.cellCount = self.cellCount - 1;

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

            } completion:^(BOOL finished) {

                [self.collectionView reloadData];

            }];

        } else {

            [self.collectionView performBatchUpdates:^{

                self.cellCount = self.cellCount + 1;

                [self.collectionView insertItemsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForItem:(random()%self.cellCount) inSection:0]]];

            } completion:^(BOOL finished) {

                [self.collectionView reloadData];

            }];

        }

    }

}

 

 

#pragma mark <UICollectionViewDataSource>

 

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {

    return 1;

}

 

 

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

    return _cellCount;

}

 

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

    WQCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];

    [cell updateAppreanceAccrodingToItem:indexPath.item];

    cell.contentView.backgroundColor = [UIColor redColor];

    cell.contentView.layer.cornerRadius = 20;

    cell.contentView.layer.masksToBounds = YES;

    

//    UILabel *lbl = [[UILabel alloc] init];

//    lbl.center = cell.contentView.center;

//    lbl.text = [NSString stringWithFormat:@"%ld", indexPath.item];

//    [lbl sizeToFit];

//    [cell.contentView addSubview:lbl];

//    

    return cell;

}

 

#pragma mark <UICollectionViewDelegate>

 

/*

// Uncomment this method to specify if the specified item should be highlighted during tracking

- (BOOL)collectionView:(UICollectionView *)collectionView shouldHighlightItemAtIndexPath:(NSIndexPath *)indexPath {

return YES;

}

*/

 

/*

// Uncomment this method to specify if the specified item should be selected

- (BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath {

    return YES;

}

*/

 

/*

// Uncomment these methods to specify if an action menu should be displayed for the specified item, and react to actions performed on the item

- (BOOL)collectionView:(UICollectionView *)collectionView shouldShowMenuForItemAtIndexPath:(NSIndexPath *)indexPath {

return NO;

}

 

- (BOOL)collectionView:(UICollectionView *)collectionView canPerformAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {

return NO;

}

 

- (void)collectionView:(UICollectionView *)collectionView performAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {

 

}

*/

 

@end

 

~~~~~~~~~~~~~~~~~~~~~~~~

#import <UIKit/UIKit.h>

 

@interface WQCollectionViewCell : UICollectionViewCell

 

- (void)updateAppreanceAccrodingToItem:(NSInteger)item;

 

@end

#import "WQCollectionViewCell.h"

 

@interface WQCollectionViewCell ()

 

@property(strong, nonatomic)UILabel               *lbl;

 

@end

 

@implementation WQCollectionViewCell

 

-(void)prepareForReuse {

    _lbl.text = nil;

}

 

- (void)updateAppreanceAccrodingToItem:(NSInteger)item {

    self.lbl.text = [NSString stringWithFormat:@"%ld", item];

    [self addSubview:self.lbl];

}

 

- (UILabel *)lbl {

    if (_lbl == nil) {

        _lbl = [[UILabel alloc] init];

        [_lbl setFont:[UIFont systemFontOfSize:12.0f]];

        _lbl.textAlignment = NSTextAlignmentCenter;

        _lbl.frame = CGRectMake(10, 10, 20, 20);

    }

    return _lbl;

}

 

@end

~~~~~~~~~~~~~~~~~~~~~自定义layout

#import <UIKit/UIKit.h>

 

@interface WQCollectionViewCircleLayout : UICollectionViewLayout

 

@end

#define ITEM_SIZE           40.0f

 

#import "WQCollectionViewCircleLayout.h"

 

@interface WQCollectionViewCircleLayout ()

 

@property(assign, nonatomic) NSInteger           cellCount;

@property(assign, nonatomic) CGPoint             center;

@property(assign, nonatomic) CGFloat             radius;

@property(strong, nonatomic) NSMutableArray      *indexPathToAnimation;

 

@end

 

@implementation WQCollectionViewCircleLayout

 

- (void)prepareLayout {

    [super prepareLayout];

    

    CGSize size = self.collectionView.frame.size;

    _cellCount = [self.collectionView numberOfItemsInSection:0];

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

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

    _radius = 120;

}

 

- (CGSize)collectionViewContentSize {

    return self.collectionView.frame.size;

}

 

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

    NSMutableArray *attributes = [NSMutableArray array];

    for (int i = 0; i < _cellCount; i ++) {

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

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

    }

    return attributes;

}

 

-(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {

    CGRect oldBounds = self.collectionView.bounds;

    if (CGRectGetWidth(newBounds) != CGRectGetWidth(oldBounds) || CGRectGetHeight(newBounds) != CGRectGetWidth(oldBounds)) {

        return YES;

    }

    return NO;

}

 

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

    UICollectionViewLayoutAttributes *layoutAttributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];

    layoutAttributes.size = CGSizeMake(ITEM_SIZE, ITEM_SIZE);

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

    NSLog(@"%@", NSStringFromCGRect(layoutAttributes.frame));

    return layoutAttributes;

}

 

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

    [super prepareForCollectionViewUpdates:updateItems];

    

    NSMutableArray *attrsArray = [NSMutableArray array];

    for (UICollectionViewUpdateItem *updateItem in updateItems) {

        switch (updateItem.updateAction) {

            case UICollectionUpdateActionInsert:

            {

                NSIndexPath *itemIndex = updateItem.indexPathAfterUpdate;

                [attrsArray addObject:itemIndex];

            }

                break;

            case UICollectionUpdateActionDelete:

            {

                NSIndexPath *itemIndex = updateItem.indexPathBeforeUpdate;

                [attrsArray addObject:itemIndex];

            }

                break;

            case UICollectionUpdateActionMove:

            {

                NSIndexPath *itemIndexBeforeUpdate = updateItem.indexPathBeforeUpdate;

                NSIndexPath *itemIndexAfterUpdate = updateItem.indexPathAfterUpdate;

                [attrsArray addObject:itemIndexBeforeUpdate];

                [attrsArray addObject:itemIndexAfterUpdate];

            }

                break;

            case UICollectionUpdateActionReload:

                

                break;

            case UICollectionUpdateActionNone:

                

                break;

            default:

                break;

        }

    }

    _indexPathToAnimation = attrsArray;

}

 

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

    UICollectionViewLayoutAttributes *layoutAttr = [self layoutAttributesForItemAtIndexPath:itemIndexPath];

    if ([_indexPathToAnimation containsObject:itemIndexPath]) {

        layoutAttr.transform = CGAffineTransformRotate(CGAffineTransformMakeScale(0.2, 0.2), M_PI);

        layoutAttr.center = CGPointMake(self.collectionView.center.x, self.collectionView.bounds.size.height);

//        layoutAttr.center = CGPointMake(CGRectGetMidX(self.collectionView.bounds), CGRectGetMidY(self.collectionView.bounds));

        [self.indexPathToAnimation removeObject:itemIndexPath];

    }

    return layoutAttr;

}

 

@end

 

~~~~~~~~~~~~~实现效果:

posted @ 2015-12-15 14:09  乔胖胖  阅读(448)  评论(0编辑  收藏  举报