zoukankan      html  css  js  c++  java
  • 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

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

  • 相关阅读:
    多线程GCD(二)
    多线程
    Runtime & Runloop
    MTK android 重启测试脚本
    ubuntu samba 配置简介
    Gerrit使用简介
    MTK andorid从底层到上层添加驱动
    MTK GPIO 新增变量配置
    MT6755 使用R63350 IC 出现唤醒概率性闪白,并导致ESD FAIL
    android L版本AAL新架构
  • 原文地址:https://www.cnblogs.com/Jordandan/p/5048160.html
Copyright © 2011-2022 走看看