• iOS UICollectionView基础


     

    转载自:http://www.cnblogs.com/wayne23/p/4013522.html 

    初始化部分:

    复制代码
    UICollectionViewFlowLayout *flowLayout= [[UICollectionViewFlowLayout alloc]init];
    self.myCollectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(20, 20, 250, 350) collectionViewLayout:flowLayout];
    self.myCollectionView.backgroundColor = [UIColor grayColor];
    [self.myCollectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@“myCell"];
    self.myCollectionView.delegate = self;
    self.myCollectionView.dataSource = self;
    
    [self.view addSubview:self.myCollectionView];
    复制代码

     

    UICollectionViewLayout

    UICollectionViewLayout决定了UICollectionView如何显示在界面上,Apple提供了一个最简单的默认layout对象:UICollectionViewFlowLayout。

    Flow Layout是一个Cells的线性布局方案,并具有页面和页脚。其可定制的内容如下:

    itemSize属性

    设定全局的Cell尺寸,如果想要单独定义某个Cell的尺寸,可以使用下面方法:

    - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath

    minimumLineSpacing属性

    设定全局的行间距,如果想要设定指定区内Cell的最小行距,可以使用下面方法:

    - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section

    minimumInteritemSpacing属性

    设定全局的Cell间距,如果想要设定指定区内Cell的最小间距,可以使用下面方法:

    - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section;

    scrollDirection属性

    设定滚动方向,有UICollectionViewScrollDirectionVerticalUICollectionViewScrollDirectionHorizontal两个值。

    headerReferenceSize属性与footerReferenceSize属性

    设定页眉和页脚的全局尺寸,需要注意的是,根据滚动方向不同,header和footer的width和height中只有一个会起作用。如果要单独设置指定区内的页面和页脚尺寸,可以使用下面方法:

    - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section

    - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section

    sectionInset属性

    设定全局的区内边距,如果想要设定指定区的内边距,可以使用下面方法:

    - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section;


     

    然后需要实现三种类型的委托:UICollectionViewDataSource, UICollectionViewDelagate和UICollectionViewDelegateFlowLayout

    @interface ViewController : UIViewController <UICollectionViewDelegateFlowLayout, UICollectionViewDataSource>

    因为UICollectionViewDelegateFlowLayout实际上是UICollectionViewDelegate的一个子协议,它继承了UICollectionViewDelegate,所以只需要在声明处写上UICollectionViewDelegateFlowLayout就行了。


     

    UICollectionViewDataSource

    - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView

    返回collection view里区(section)的个数,如果没有实现该方法,将默认返回1:

    - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
    {
        return 2;
    }

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

    返回指定区(section)包含的数据源条目数(number of items),该方法必须实现:

    - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
    {
        return 7;
    }

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

    返回某个indexPath对应的cell,该方法必须实现:

    复制代码
    - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
    {
        UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"myCell" forIndexPath:indexPath];
        if(indexPath.section==0)
        {
            cell.backgroundColor = [UIColor redColor];
        }
        else if(indexPath.section==1)
        {
            cell.backgroundColor = [UIColor greenColor];
        }
        return cell;
    }
    复制代码

    UICollectionViewCell结构上相对比较简单,由下至上:

    • 首先是cell本身作为容器view
    • 然后是一个大小自动适应整个cell的backgroundView,用作cell平时的背景
    • 再其次是selectedBackgroundView,是cell被选中时的背景
    • 最后是一个contentView,自定义内容应被加在这个view

    - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString*)kind atIndexPath:(NSIndexPath *)indexPath

    为collection view添加一个补充视图(页眉或页脚)

     

    - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section

    设定页眉的尺寸

     

    - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section

    设定页脚的尺寸

     

    - (void)registerClass:(Class)viewClass forSupplementaryViewOfKind:(NSString *)elementKind withReuseIdentifier:(NSString*)identifier

    添加页眉和页脚以前需要注册类和标识:


     

    添加补充视图的代码示例:

    复制代码
    [self.myCollectionView registerClass:[MyHeadView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"hxwHeader"];
    [self.myCollectionView registerClass:[MyHeadView class] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"hxwHeader"];
    
    -(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section
    {
        CGSize size = {240,25};
        return size;
    }
    
    -(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section
    {
        CGSize size = {240,25};
        return size;
    }
    
    - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
    {
        MyHeadView *headView;
        
        if([kind isEqual:UICollectionElementKindSectionHeader])
        {
             headView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"hxwHeader" forIndexPath:indexPath];
            [headView setLabelText:[NSString stringWithFormat:@"section %d's header",indexPath.section]];
        }
        else if([kind isEqual:UICollectionElementKindSectionFooter])
        {
            headView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"hxwHeader" forIndexPath:indexPath];
            [headView setLabelText:[NSString stringWithFormat:@"section %d's footer",indexPath.section]];
        }
        return headView;
    }
    复制代码

     

    MyHeadView.h

    #import <UIKit/UIKit.h>
    
    @interface MyHeadView : UICollectionReusableView
    - (void) setLabelText:(NSString *)text;
    @end

    MyHeadView.m

    复制代码
    #import "MyHeadView.h"
    
    @interface MyHeadView()
    
    @property (strong, nonatomic) UILabel *label;
    
    @end
    
    @implementation MyHeadView
    
    - (id)initWithFrame:(CGRect)frame
    {
        self = [super initWithFrame:frame];
        if (self)
        {
            self.label = [[UILabel alloc] init];
            self.label.font = [UIFont systemFontOfSize:18];
            [self addSubview:self.label];
        }
        return self;
    }
    
    - (void) setLabelText:(NSString *)text
    {
        self.label.text = text;
        [self.label sizeToFit];
    }
    
    @end
    复制代码

    在注册Cell和补充视图时,也可以用新建xib文件的方式:

    复制代码
    [self.myCollectionView registerNib:[UINib nibWithNibName:@"MyCollectionCell" bundle:nil] forCellWithReuseIdentifier:@"hxwCell"];
    
    [self.myCollectionView registerNib:[UINib nibWithNibName:@"MySupplementaryView" bundle:nil] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"hxwHeader"];
        
    [self.myCollectionView registerNib:[UINib nibWithNibName:@"MySupplementaryView" bundle:nil] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"hxwFooter"];
    复制代码

    用这种方式注册后,甚至可以不用新建类去绑定这个xib,直接通过viewWithTag的方式获取xib里的控件:

    UICollectionReusableView *view =  [collectionView dequeueReusableSupplementaryViewOfKind :kind withReuseIdentifier:@"hxwHeader" forIndexPath:indexPath];
    
    UILabel *label = (UILabel *)[view viewWithTag:1];
    
    label.text = @"empty";

    UICollectionViewDelegateFlowLayout

    - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath

    设定指定Cell的尺寸

    复制代码
    - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
    {
        if(indexPath.section==0 && indexPath.row==1)
        {
            return CGSizeMake(50, 50);
        }
        else
        {
            return CGSizeMake(75, 30);
        }
    }
    复制代码

    - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section;

    设定collectionView(指定区)的边距

    复制代码
    - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
    {
        if(section==0)
        {
            return UIEdgeInsetsMake(35, 25, 15, 25);
        }
        else
        {
            return UIEdgeInsetsMake(15, 15, 15, 15);
        }
    }
    复制代码

    - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section

    设定指定区内Cell的最小行距,也可以直接设置UICollectionViewFlowLayout的minimumLineSpacing属性

    复制代码
    - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section
    {
        if(section==0)
        {
            return 10.0;
        }
        else
        {
            return 20.0;
        }
    }
    复制代码

    - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section;

    设定指定区内Cell的最小间距,也可以直接设置UICollectionViewFlowLayoutminimumInteritemSpacing属性

    复制代码
    - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section
    {
        if(section==0)
        {
            return 10.0;
        }
        else
        {
            return 20.0;
        }
    }
    复制代码

    UICollectionViewDelegate

    - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath

    当指定indexPath处的item被选择时触发

    - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
    {
    [self.myArray removeObjectAtIndex:indexPath.row];
    
    [collectionView deleteItemsAtIndexPaths:[NSArray arrayWithObject:indexPath]];
    }

    P.s. 当你删除或添加元素时,一定要更新numberOfItemsInSection的返回情况。

     

    - (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath

    当指定indexPath处的item被取消选择时触发,仅在允许多选时被调用

     

    下面是三个和高亮有关的方法:

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

    - (void)collectionView:(UICollectionView *)collectionView didHighlightItemAtIndexPath:(NSIndexPath *)indexPath

    - (void)collectionView:(UICollectionView *)collectionView didUnhighlightItemAtIndexPath:(NSIndexPath *)indexPath

     

    事件的处理顺序如下:

    1. 手指按下
    2. shouldHighlightItemAtIndexPath (如果返回YES则向下执行,否则执行到这里为止)
    3. didHighlightItemAtIndexPath (高亮)
    4. 手指松开
    5. didUnhighlightItemAtIndexPath (取消高亮)
    6. shouldSelectItemAtIndexPath (如果返回YES则向下执行,否则执行到这里为止)
    7. didSelectItemAtIndexPath (执行选择事件)

    如果只是简单实现点击后cell改变显示状态,只需要在cellForItemAtIndexPath方法里返回cell时,指定cell的selectedBackgroundView:

    复制代码
    - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
    {
        UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"myCell" forIndexPath:indexPath];
        
        UIView* selectedBGView = [[UIView alloc] initWithFrame:cell.bounds];
        selectedBGView.backgroundColor = [UIColor blueColor];
        cell.selectedBackgroundView = selectedBGView;
        
        return cell;
    }
    复制代码

    如果要实现点击时(手指未松开)的显示状态与点击后(手指松开)的显示状态,则需要通过上面提到的方法来实现:

    复制代码
    - (BOOL)collectionView:(UICollectionView *)collectionView shouldHighlightItemAtIndexPath:(NSIndexPath *)indexPath
    {
        return YES;
    }
    
    - (void)collectionView:(UICollectionView *)colView didHighlightItemAtIndexPath:(NSIndexPath *)indexPath
    {
        UICollectionViewCell* cell = [colView cellForItemAtIndexPath:indexPath];
        
        [cell setBackgroundColor:[UIColor purpleColor]];
    }
    
    - (void)collectionView:(UICollectionView *)colView  didUnhighlightItemAtIndexPath:(NSIndexPath *)indexPath
    {
        UICollectionViewCell* cell = [colView cellForItemAtIndexPath:indexPath];
        
        [cell setBackgroundColor:[UIColor yellowColor]];
    }
    复制代码
  • 相关阅读:
    CodeForces 734F Anton and School
    CodeForces 733F Drivers Dissatisfaction
    CodeForces 733C Epidemic in Monstropolis
    ZOJ 3498 Javabeans
    ZOJ 3497 Mistwald
    ZOJ 3495 Lego Bricks
    CodeForces 732F Tourist Reform
    CodeForces 732E Sockets
    CodeForces 731E Funny Game
    CodeForces 731D 80-th Level Archeology
  • 原文地址:https://www.cnblogs.com/niit-soft-518/p/4622122.html
Copyright © 2020-2023  润新知