• 自定义UICollectionLayout


    #import "AppDelegate.h"
    #import "CircleLayout.h"
    #import "CollectionViewDataSource.h"
    #import "MyCollectionReusableView.h"

    @interface CircleLayout()
    {
    CGSize cvSize;
    CGPoint cvCenter;
    CGFloat radius;
    NSInteger cellCount;
    }

    @property (strong, nonatomic) NSMutableArray *indexPathsToAnimate;

    @end

    @implementation CircleLayout

    - (void)prepareLayout
    {
    [super prepareLayout];

    [self registerClass:[MyCollectionReusableView class] forDecorationViewOfKind:@"MyDecoration"];

    cvSize = self.collectionView.frame.size;
    cellCount = [self.collectionView numberOfItemsInSection:0];
    cvCenter = CGPointMake(cvSize.width / 2.0, cvSize.height / 2.0);
    radius = MIN(cvSize.width, cvSize.height) / 2.5;
    }

    - (CGSize)collectionViewContentSize
    {
    return self.collectionView.bounds.size;
    }

    - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
    {
    NSMutableArray *array = [NSMutableArray array];

    //add cells
    for (int i=0; i<cellCount; i++)
    {
    NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];

    UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForItemAtIndexPath:indexPath];

    [array addObject:attributes];
    }

    //add first supplementaryView
    NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:0];
    UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForSupplementaryViewOfKind:@"FirstSupplementary" atIndexPath:indexPath];
    [array addObject:attributes];

    //add second supplementaryView
    attributes = [self layoutAttributesForSupplementaryViewOfKind:@"SecondSupplementary" atIndexPath:indexPath];
    [array addObject:attributes];

    //add decorationView
    attributes = [self layoutAttributesForDecorationViewOfKind:@"MyDecoration" atIndexPath:indexPath];
    [array addObject:attributes];

    return array;
    }

    - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
    {
    UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];

    attributes.size = CGSizeMake(20, 20);
    attributes.center = CGPointMake(cvCenter.x + radius * cosf(2 * indexPath.item * M_PI / cellCount),
    cvCenter.y + radius * sinf(2 * indexPath.item * M_PI / cellCount));

    return attributes;
    }

    - (UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath
    {
    UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForSupplementaryViewOfKind:elementKind withIndexPath:indexPath];

    attributes.size = CGSizeMake(260, 40);
    if([elementKind isEqual:@"FirstSupplementary"])
    {
    attributes.center = CGPointMake(cvSize.width/2, 40);
    }
    else
    {
    attributes.center = CGPointMake(cvSize.width/2, cvSize.height-40);
    }

    return attributes;
    }

    - (UICollectionViewLayoutAttributes *)layoutAttributesForDecorationViewOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath
    {
    UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForDecorationViewOfKind:elementKind withIndexPath:indexPath];

    attributes.size = CGSizeMake(140, 40);
    attributes.center = CGPointMake(cvSize.width/2, cvSize.height/2);

    return attributes;
    }

    //当边界更改时是否更新布局
    - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
    {
    CGRect oldBounds = self.collectionView.bounds;

    if (CGRectGetWidth(newBounds) != CGRectGetWidth(oldBounds))
    {
    return YES;
    }

    return NO;
    }

    //通知布局,collection view里有元素即将改变,这里可以收集改变的元素indexPath和action类型。
    -(void)prepareForCollectionViewUpdates:(NSArray *)updateItems
    {
    [super prepareForCollectionViewUpdates:updateItems];

    NSMutableArray *indexPaths = [NSMutableArray array];

    for(UICollectionViewUpdateItem *updateItem in updateItems)
    {
    //UICollectionUpdateActionInsert,
    //UICollectionUpdateActionDelete,
    //UICollectionUpdateActionReload,
    //UICollectionUpdateActionMove,
    //UICollectionUpdateActionNone

    NSLog(@"before index:%d,after index:%d,action:%d", updateItem.indexPathBeforeUpdate.row,updateItem.indexPathAfterUpdate.row,updateItem.updateAction);

    switch (updateItem.updateAction) {
    case UICollectionUpdateActionInsert:
    [indexPaths addObject:updateItem.indexPathAfterUpdate];
    break;
    case UICollectionUpdateActionDelete:
    [indexPaths addObject:updateItem.indexPathBeforeUpdate];
    break;
    case UICollectionUpdateActionMove:
    [indexPaths addObject:updateItem.indexPathBeforeUpdate];
    [indexPaths addObject:updateItem.indexPathAfterUpdate];
    break;
    default:
    NSLog(@"unhandled case: %@", updateItem);
    break;
    }
    }

    self.indexPathsToAnimate = indexPaths;
    }

    //当一个元素被插入collection view时,返回它的初始布局,这里可以加入一些动画效果。
    - (UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingItemAtIndexPath:(NSIndexPath *)itemIndexPath
    {
    UICollectionViewLayoutAttributes *attr = [self layoutAttributesForItemAtIndexPath:itemIndexPath];

    if([self.indexPathsToAnimate containsObject:itemIndexPath])
    {
    attr.transform = CGAffineTransformRotate(CGAffineTransformMakeScale(10,10),M_PI);
    attr.center = CGPointMake(CGRectGetMidX(self.collectionView.bounds), CGRectGetMidY(self.collectionView.bounds));
    [self.indexPathsToAnimate removeObject:itemIndexPath];
    }

    return attr;
    }

    - (NSArray *)getLetterArray
    {
    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];

    return appDelegate.letterArray;
    }

    @end

    CircleLayout.m

  • 相关阅读:
    内置方法(item系列、__str__方法、__del__方法)
    POJ3436
    CF551B
    HDU1588
    HDU3117
    CF834D
    CF832D
    CF832C
    POJ1930
    POJ3666
  • 原文地址:https://www.cnblogs.com/W-Kr/p/5143343.html
Copyright © 2020-2023  润新知