美文网首页
iOS-UICollectionView

iOS-UICollectionView

作者: 我是谁重要吗 | 来源:发表于2018-04-05 23:47 被阅读30次

    CollectionView:
    UICollectionView、UITableView、NSCollectionView
    和 UITableView 不同的是,UICollectionView 不局限于垂直的单列布局。相反,collection view有一个 layout 对象,它决定子视图的位置,

    先看后面的图片再返回来看比较好理解。

    简介:

    UICollectionView相对于UITableView很相似,都继承于UIScrollView
    UITableView的布局形式比较单一,局限于行列表,
    UICollectionView的强大之处在于把视图布局分离出来成为一个独立的类,你想实现怎样的视图布局,就子类化这个类并在其中实现。
    UICollectionView默认没有表头, UITableView: 有表头和表尾;
    UICollectionView的区里面是项Item, UITableView:区里面是单元格Cell
    collectionView和tableView最大的不同之处就是需要自定义cell, collectionView能自动的根据屏幕宽度显示横列竖!
    UICollectionView主要用于瀑布流
    UICollectionViewLayout是基类,其子类:UICollectionViewFlowLayout,使用的时候都用子类
    CollectionView中的每个Item大小和位置可以单独定义
    区别:https://blog.csdn.net/vbirdbest/article/details/50720915

    必须实现:

    1、显示内容完全由layout(布局对象)决定,必须设置UICollectionView的collectionViewLayout

    UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
        layout.minimumLineSpacing = 10;
        layout.minimumInteritemSpacing = 20;
    UICollectionView *cv = [[UICollectionView alloc] 
    initWithFrame:CGRectMake(20, 20, 300, 500) collectionViewLayout:layout];
    

    2、必须设置代理
    使用UICollectionView的时候,要声明:

    1. UICollectionViewDelegateFlowLayout
    2. UICollectionViewDataSource,
    3. UICollectionViewDelegate
    //1中包含了,所以3可以省略
    //显示什么内容由数据源决定
    //监听由代理决定
    

    3、必须注册cell

    [cv registerClass:[UICollectionViewCell class]forCellWithReuseIdentifier:@"ReusableView"];
    //ReusableView 这个名字需要和下面4中cellForItemAtIndexPath 定义的一样
    
    

    4、必须实现 (和UITableview一样) :

    cellForItemAtIndexPath //返回cell
    numberOfItemsInSection //返回多少行
    

    UICollectionViewFlowLayout

    //继承 UICollectionViewLayout
    //属性:
    minimumLineSpacing //最小行间距  
    minimumInteritemSpacing //最小内间距(列间距
    itemSize
    estimatedItemSize
    scrollDirection
    headerReferenceSize
    footerReferenceSize
    sectionInset // 段的上下左右的内边距 padding(多个分区一般都会设置该值,如果不设置,多个区会连在一块)  
    //方法:
    - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath;
    - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section;
    - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section;
    - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section;
    - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section;
    - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section;
    
    

    UICollectionViewLayout

    UICollectionViewLayout的精髓在于你可以定义每个cell的UICollectionViewLayoutAttributes属性

    //属性:
    frame
    center
    size
    transform3D //可以实现视图的旋转、放大以及透视等效果
    bounds
    transform
    alpha
    zIndex
    hidden
    indexPath
    collectionView
    
    //方法:
    invalidateLayout
    prepareLayout
    -(UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
    
    

    UICollectionView

    //继承 UIScrollView
    //属性
    delegate
    dataSource
    backgroundView
    showsHorizontalScrollIndicator
    showsVerticalScrollIndicator
    .bounces //弹簧效果
    
    //方法
    //初始化要设置layout
    - (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout 
    //注册cell
    - (void)registerClass:(nullable Class)cellClass forCellWithReuseIdentifier:(NSString *)identifier;
    //注册头尾
    - (void)registerClass:(nullable Class)viewClass forSupplementaryViewOfKind:(NSString *)elementKind withReuseIdentifier:(NSString *)identifier;
    - (__kindof UICollectionViewCell *)dequeueReusableCellWithReuseIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath;
    - (__kindof UICollectionReusableView *)dequeueReusableSupplementaryViewOfKind:(NSString *)elementKind withReuseIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath;
    reloadData
    //@required
    //每个section有多少Items
    - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section;
    //cell内容
    - (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath;
    @optional
    //多少Sections
    - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
    //选中后
    - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
    // 取消选中操作  
    - (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath
    //设置是否允许选中
    - (BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath
    // 设置是否允许取消选中  
    - (BOOL)collectionView:(UICollectionView *)collectionView shouldDeselectItemAtIndexPath:(NSIndexPath *)indexPath
    //动态设置每个Item的尺寸大小
    - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath;
    //动态设置每个分区的EdgeInsets
    - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section;
    //动态设置每行的间距大小
    - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section;
    //动态设置每列的间距大小
    - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section;
    //动态设置某组头视图大小
    - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section;
    //动态设置某组尾视图大小
    - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section;
    //设置段头段位
    - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath{
    //下面这两个方法,可以重新设置collection的布局,后面的方法多了一个布局完成后的回调,iOS7后可以用
    //使用这两个方法可以产生非常炫酷的动画效果
    - (void)setCollectionViewLayout:(UICollectionViewLayout *)layout animated:(BOOL)animated;
    - (void)setCollectionViewLayout:(UICollectionViewLayout *)layout animated:(BOOL)animated completion:(void (^ __nullable)(BOOL finished))completion NS_AVAILABLE_IOS(7_0);
    
    //下面这些方法用于动态添加,删除,移动某些分区获取items
    - (void)insertSections:(NSIndexSet *)sections;
    - (void)deleteSections:(NSIndexSet *)sections;
    - (void)reloadSections:(NSIndexSet *)sections;
    - (void)moveSection:(NSInteger)section toSection:(NSInteger)newSection;
    
    - (void)insertItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths;
    - (void)deleteItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths;
    - (void)reloadItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths;
    - (void)moveItemAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath;
    
    

    UICollectionViewCell

    //继承 UICollectionReusableView :UIView
    //属性:
    contentView
    selected
    highlighted
    backgroundView
    selectedBackgroundView
    
    //方法:
    
    

    代码 实例:

    static NSString *const cellId = @"ReusableView";
    static NSString *const headerId = @"ReusableHeaderView";
    static NSString *const footerId = @"ReusableFooterView";
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        self.view.backgroundColor = [UIColor orangeColor];
        //UICollectionViewLayout *layout = [[UICollectionViewLayout alloc] init];
        UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
        layout.minimumLineSpacing = 10;
        layout.minimumInteritemSpacing = 20;
        layout.itemSize = CGSizeMake(50, 50);
        layout.headerReferenceSize = CGSizeMake(300, 50);
        layout.footerReferenceSize = CGSizeMake(300, 50);
        layout.sectionInset = UIEdgeInsetsMake(10, 10, 0, 10);
        layout.scrollDirection = UICollectionViewScrollDirectionVertical;
        
        UICollectionView *cv = [[UICollectionView alloc] initWithFrame:CGRectMake(20, 20, 300, 500) collectionViewLayout:layout];
        cv.backgroundColor = [UIColor blackColor];
        cv.delegate = self;
        cv.dataSource = self;
        
        [cv registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"ReusableView"];
        [cv registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"ReusableHeaderView"];
        [cv registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"ReusableFooterView"];
    
        //[cv registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"ReusableView"];
        
        [self.view addSubview:cv];
        
    }
    
    - (nonnull __kindof UICollectionViewCell *)collectionView:(nonnull UICollectionView *)collectionView cellForItemAtIndexPath:(nonnull NSIndexPath *)indexPath { 
        
         NSString *cvCell = @"ReusableView";
        UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cvCell forIndexPath:indexPath];
        //UICollectionViewCell * cell = [[UICollectionViewCell alloc]init]; 这样崩溃,必须如上复用。也不用对cell进行空值判断 if(!cell){}
    
        //CollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cvCell forIndexPath:indexPath];
        
        [cell sizeToFit];
        UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"%ld",indexPath.row]];
        UIImageView *imageV = [[UIImageView alloc] initWithImage:image];
        imageV.frame = CGRectMake(0, 0, 30, 30);
        [cell.contentView addSubview:imageV];
        if (indexPath.section % 2 == 0) {
            cell.backgroundColor = [UIColor whiteColor];
        }else{
            cell.backgroundColor = [UIColor redColor];
        }
            return cell;
    }
    - (NSInteger)collectionView:(nonnull UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
        return 10;
    }
    
    - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
        
        return 2 ;
    }
    
    -(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
        if (indexPath.row%2 == 0) {
            return CGSizeMake(60, 80);
        }else{
            return CGSizeMake(80, 60);
        }
        return CGSizeMake(60, 80);
    }
    
    - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
        
        NSLog(@"click cell");
        
    }
    
    //footer的size
    - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section
    {
        return CGSizeMake(10, 10);
    }
    
    //header的size
    - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section
    {
        return CGSizeMake(10, 10);
    }
    
    //设置每个item的UIEdgeInsets
    - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
    {
        return UIEdgeInsetsMake(10, 10, 10, 10);
    }
    
    //设置每个item水平间距
    - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section
    {
        return 10;
    }
    
    
    //设置每个item垂直间距
    - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section
    {
        return 15;
    }
    
    // 和UITableView类似,UICollectionView也可设置段头段尾
    - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath{
        
        if([kind isEqualToString:UICollectionElementKindSectionHeader]){
            UICollectionReusableView * headerView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader                                                                           withReuseIdentifier:@"ReusableView"                                                                              forIndexPath:indexPath];  
        UIView * contentView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 50)];  
        contentView.backgroundColor = [UIColor grayColor];  
        UILabel * label = [[UILabel alloc] initWithFrame:CGRectMake(20, 10, self.view.frame.size.width, 30)];  
        label.text = [NSString stringWithFormat:@"Section Header: %ld", indexPath.section];  
        label.textAlignment = NSTextAlignmentCenter;  
        [contentView addSubview:label];  
        [headerView addSubview:contentView];  
        return headerView;  
        }
        else if([kind isEqualToString:UICollectionElementKindSectionFooter]){
            
        }
        
        return nil;
    }
    
    - (BOOL)collectionView:(UICollectionView *)collectionView canMoveItemAtIndexPath:(NSIndexPath *)indexPath
    {
        return YES;
    }
    
    
    - (void)collectionView:(UICollectionView *)collectionView moveItemAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath*)destinationIndexPath
    {
        
    }
    
    
    区别.png 垂直水平排列.png 1648725-81eb0f19e60dbaeb.jpg 屏幕快照 2018-05-28 13.48.22.png 在实际开发过程中,很可能行间距会是不同的.png

    问题:

    1、cell 重叠 ?
    自定义UICollectionViewCell

    参考:
    https://blog.csdn.net/lvxiangan/article/details/73826108 超全
    https://blog.csdn.net/eqera/article/details/8134986
    https://www.jianshu.com/p/cf616f73d596 实践

    https://blog.csdn.net/vbirdbest/article/details/50720915 有图

    相关文章

      网友评论

          本文标题:iOS-UICollectionView

          本文链接:https://www.haomeiwen.com/subject/fjalhftx.html