关于利用UICollectionView展示图片的实现

  对于2012年苹果公司推出的新技术,同时继承自UIScrollView的UICollectionView在使用方面和与UITableView极其相似,有两个必须遵守的协议,也有两个必须实现的方法,同时每个显示的View可称为Cell单元格,但是UICollectionView多了layout的布局类,其使用更灵活,可以高度自定义,其布局对象layout仅与显示有关,与数据源无关。下面用一个简单的Demo来演示UICollectionView的使用:

第一步:创建一个工程,可以是Empty Application或是SingleViewApplication(就是是否使用StoryBoard)

第二步:创建一个ViewController并选择其继承的类可以是ViewController,也可以是UICollectionViewController,如果是view controller则需要在遵循两个协议;

@interface QYViewController : UIViewController

如果是后者则是默认遵循

@interface QYMainViewController : UICollectionViewController

第三步:实现datasource代理的两个必要条件

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.cellCount = 10;
    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(onTapGesture:)];
    [self.collectionView addGestureRecognizer:tapGesture];
   [self.collectionView reloadData];
}

#pragma mark - 

#pragma mark collectionView DataSource

-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return self.cellCount;
}
-(UICollectionViewCell*)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    QYCell *cell  = [collectionView dequeueReusableCellWithReuseIdentifier:cellIndentifier forIndexPath:indexPath];
    cell.layer.cornerRadius = 5.0;
    cell.contentView.layer.borderWidth = 2.0f;
    cell.contentView.layer.borderColor = [UIColor blueColor].CGColor;
    UIImageView *imageView = [[UIImageView alloc]initWithFrame:cell.contentView.frame];
    imageView.image = [UIImage imageNamed:@"favorite"];
    [cell.contentView addSubview:imageView];
    return cell;
}
第四步: 如果想自定义显示布局,则需要子类化layout布局对象,重写其中的方法

.h文件

@interface QYCircleLayout : UICollectionViewFlowLayout
@property (assign, nonatomic) CGPoint center;
@property (assign, nonatomic) CGFloat radius;
@property (assign, nonatomic) NSInteger cellCount;
@end

.m文件
@interface QYCircleLayout ()

@property (strong, nonatomic) NSMutableArray *deleteIndexPath;
@property (strong, nonatomic) NSMutableArray *insertIndexpath;

@end

@implementation QYCircleLayout

-(void)prepareLayout
{
    [super prepareLayout];
    CGSize size = self.collectionView.frame.size;
    _cellCount = [[self collectionView]numberOfItemsInSection:0];
    _center = CGPointMake(size.width / 2.0, size.height / 2.0);
    _radius = MIN(size.width, size.height)/2.5;

}
-(CGSize)collectionViewContentSize
{
    return [self collectionView].frame.size;
}
-(UICollectionViewLayoutAttributes*)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
    UICollectionViewLayoutAttributes *attrubite = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
    attrubite.size = CGSizeMake(ITEM_SIZE, ITEM_SIZE);
    attrubite.center = CGPointMake(_center.x + _radius * cosf(2 * indexPath.item * M_PI / _cellCount),
                                   _center.y + _radius * sinf(2 * indexPath.item * M_PI / _cellCount));
    
    return attrubite;
}

-(NSArray*)layoutAttributesForElementsInRect:(CGRect)rect
{
    NSMutableArray *attrubites = [NSMutableArray array];
    for (NSInteger i = 0; i < self.cellCount; i++) {
        NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];
        [attrubites addObject:[self layoutAttributesForItemAtIndexPath:indexPath]];
    }
    return attrubites;
}

-(void)prepareForCollectionViewUpdates:(NSArray *)updateItems
{
    [super prepareForCollectionViewUpdates:updateItems];
    self.deleteIndexPath = [NSMutableArray array];
    self.insertIndexpath = [NSMutableArray array];
    for (UICollectionViewUpdateItem *updateItem in updateItems) {
        if (updateItem.updateAction == UICollectionUpdateActionDelete ) {
            [self.deleteIndexPath addObject:updateItem.indexPathBeforeUpdate];
        }else if (updateItem.updateAction == UICollectionUpdateActionInsert)
        {
            [self.insertIndexpath addObject:updateItem.indexPathAfterUpdate];
        }
    }
}
-(void)finalizeCollectionViewUpdates
{
    [super finalizeCollectionViewUpdates];
    self.deleteIndexPath = nil;
    self.insertIndexpath = nil;
}
-(UICollectionViewLayoutAttributes*)initialLayoutAttributesForAppearingItemAtIndexPath:(NSIndexPath *)itemIndexPath
{
//    UICollectionViewLayoutAttributes *attribite = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:itemIndexPath];
    UICollectionViewLayoutAttributes *attribite = [super initialLayoutAttributesForAppearingItemAtIndexPath:itemIndexPath];
    if ([self.insertIndexpath containsObject:itemIndexPath]) {
        if (!attribite) {
            attribite = [self layoutAttributesForItemAtIndexPath:itemIndexPath];
            attribite.alpha = 0.0;
            attribite.center = CGPointMake(_center.x, _center.y);
        }
    }
    return attribite;
}
-(UICollectionViewLayoutAttributes*)finalLayoutAttributesForDisappearingItemAtIndexPath:(NSIndexPath *)itemIndexPath
{
    
       UICollectionViewLayoutAttributes *attribute = [super finalLayoutAttributesForDisappearingItemAtIndexPath:itemIndexPath];
    if ([self.deleteIndexPath  containsObject:itemIndexPath]) {
        if (!attribute) {
            attribute = [self layoutAttributesForItemAtIndexPath:itemIndexPath];
            attribute.alpha = 0.0 ;
            attribute.center = CGPointMake(_center.x, _center.y);
            attribute.transform3D = CATransform3DMakeScale(0.1, 0.1, 1.0);
        }
    }
    return attribute;

}

@end
最后,运行程序,就能显示出结果


对于是否使用storyBoard有以下两点需要注意:

第一点:在使用storyBoard来创建UICollectionView时,如果又重新子类化了UICollectionViewCell那么在创建cell时不会调用子类化中初始化方法中的设置。

第二点:如果使用storyBoard中的静态cell那么就不能在代码中实现datasource的两个必需实现的方法



你可能感兴趣的:(iOS开发,自定义布局,Layout)