iOS 界面之UICollectionView---总结

来源:互联网 发布:ubuntu搭建php开发环境 编辑:程序博客网 时间:2024/05/22 01:38

总结背景:

iOS--10.3

Xcode--8.3.3


一.基础

1.UICollectionViewLayout:

  An abstract base class for generating layout information for a collection view.

  The job of a layout object is to determine the placement of cells, supplementary views, and decoration views inside the collection view’s bounds and to report that information to the collection view when asked. The collection view then applies the provided layout information to the corresponding views so that they can be presented onscreen.

  You must subclass UICollectionViewLayout in order to use it. Before you consider subclassing, though, you should look at the UICollectionViewFlowLayout class to see if it can be adapted to your layout needs.


2.UICollectionViewFlowLayout:
 我们在使用的时候,主要看这个类,它继承自 UICollectionViewLayout.

3.代理:
UIViewCollectionDataSource
UIViewCollectionDelegate
UIViewCollectionDelegateFlowLayout

二.例程

1.创建集合视图,简单显示

#import "MainViewController.h"#define StatusBarHeight [[UIApplication sharedApplication] statusBarFrame].size.height#define NavBarHeight self.navigationController.navigationBar.frame.size.height#define ScreenWidth [UIScreen mainScreen].bounds.size.width#define ScreenHeight [UIScreen mainScreen].bounds.size.height@interface MainViewController ()<UICollectionViewDelegate,UICollectionViewDelegateFlowLayout,UICollectionViewDataSource>@property(nonatomic,strong) UICollectionView *collectionView;@end@implementation MainViewControllerstatic NSString *const cellID = @"collectionCell";static NSString *const headerID = @"collectionHeader";static NSString *const footerID = @"collectionFooter";- (void)viewDidLoad {    [super viewDidLoad];    [self createUI];}#pragma mark- --集合视图代理--//section数量- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{    return 2;}//cell数量- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{    return 5;}//cell视图-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{    UICollectionViewCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:cellID forIndexPath:indexPath];    cell.backgroundColor=[UIColor blueColor];    return cell;}//头部和尾部视图-(UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath{    if ([kind isEqualToString:UICollectionElementKindSectionHeader]) {        UICollectionReusableView *headerView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:headerID forIndexPath:indexPath];        headerView.backgroundColor = [UIColor grayColor];        return headerView;    }else if([kind isEqualToString:UICollectionElementKindSectionFooter]){        UICollectionReusableView *footerView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:footerID forIndexPath:indexPath];        footerView.backgroundColor = [UIColor yellowColor];        return footerView;    }    return nil;}//cells集合四周的间隔尺寸- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section{    return UIEdgeInsetsMake(5, 5, 5, 5);}//头部视图尺寸- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section{    return CGSizeMake(ScreenWidth, 30);}//尾部视图尺寸- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section{    return CGSizeMake(ScreenWidth, 30);}//cell尺寸- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{    return CGSizeMake(115, 100);}#pragma mark- --创建视图--- (void)createUI{    //集合视图布局类    UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];    layout.minimumLineSpacing = 5;    layout.minimumInteritemSpacing = 5;        //初始化集合视图    _collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 0, ScreenWidth, ScreenHeight-(NavBarHeight+StatusBarHeight)) collectionViewLayout:layout];    _collectionView.backgroundColor = [UIColor whiteColor];    _collectionView.delegate = self;    _collectionView.dataSource = self;    [self.view addSubview:_collectionView];        //注册cell,header,footer    [_collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:cellID];    [_collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:headerID];    [_collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:footerID];    }

再看下点击事件:

//cell的点击事件-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{    NSLog(@"%ld",indexPath.row);}

对于添加一个 cell ,我们可以更新数据源,然后 reloadData .

2.多选编辑效果:

为了效果好一点,需要自定义 cell 了,代码:

#import <UIKit/UIKit.h>@interface LearnCollectionViewCell : UICollectionViewCell@property(nonatomic,strong) UIImageView *selectView;@property(nonatomic,strong) UILabel *titleLabel;@property(nonatomic,copy) NSString *titleString;@end

#import "LearnCollectionViewCell.h"@implementation LearnCollectionViewCell- (instancetype)initWithFrame:(CGRect)frame{    self = [super initWithFrame:frame];    if(self){        _selectView = [[UIImageView alloc] initWithFrame:CGRectMake(self.frame.size.width-30, self.frame.size.height-30, 20, 20)];        _selectView.image = [UIImage imageNamed:@"circleSel"];        _selectView.hidden = YES;        [self addSubview:_selectView];                _titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(5, 5, 50, 30)];        [self addSubview:_titleLabel];    }    return self;}- (void)setTitleString:(NSString *)titleString{    _titleLabel.text = titleString;}@end

这里的 selectView 用来表示 cell 是否被选中


接下来在导航条里增加编辑和完成按钮:

    //设置导航条    UIBarButtonItem *rightBarBtn = [[UIBarButtonItem alloc] initWithTitle:@"编辑" style:UIBarButtonItemStylePlain target:self action:@selector(editBtnAction:)];    [self.navigationItem setRightBarButtonItem:rightBarBtn];        UIBarButtonItem *leftBarBtn = [[UIBarButtonItem alloc] initWithTitle:@"完成" style:UIBarButtonItemStylePlain target:self action:@selector(doneBtnAction:)];    [self.navigationItem setLeftBarButtonItem:leftBarBtn];


增加编辑状态量和删除缓存:

@property(nonatomic,strong) NSMutableArray *deleteCache;@property(nonatomic,assign) BOOL isEdit;

在编辑按钮Action中:

- (void)editBtnAction:(UIButton *)btn{    UIBarButtonItem *rightBtnItem = self.navigationItem.rightBarButtonItem;    if(!_isEdit){        rightBtnItem.title = @"取消";        _isEdit = YES;    }else{        for(NSNumber *num in self.deleteCache){            NSInteger row = num.integerValue;            NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:0];            LearnCollectionViewCell *cell = (LearnCollectionViewCell *)[self.collectionView cellForItemAtIndexPath:indexPath];            cell.selectView.hidden = YES;        }        [self.deleteCache removeAllObjects];        rightBtnItem.title = @"编辑";        _isEdit = NO;    }}
在完成按钮Action中:

- (void)doneBtnAction:(UIButton *)btn{    NSMutableArray *listArray = [self.sectionArray objectAtIndex:0];        for(NSNumber *num in self.deleteCache){        NSInteger row = num.integerValue;        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:0];        LearnCollectionViewCell *cell = (LearnCollectionViewCell *)[self.collectionView cellForItemAtIndexPath:indexPath];        cell.selectView.hidden = YES;        [listArray removeObjectAtIndex:row];    }        [self.deleteCache removeAllObjects];        UIBarButtonItem *rightBtnItem = self.navigationItem.rightBarButtonItem;    rightBtnItem.title = @"编辑";    _isEdit = NO;        [self.collectionView reloadData];}
cell的配置方法中:

//cell视图-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{    LearnCollectionViewCell *cell=(LearnCollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:cellID forIndexPath:indexPath];    cell.layer.borderWidth = 5.0;    cell.layer.borderColor = [UIColor blackColor].CGColor;        NSMutableArray *items = [self.sectionArray objectAtIndex:indexPath.section];        if(indexPath.row < [items count]){//        cell.backgroundColor = QSRandomColor;        cell.backgroundColor = [UIColor whiteColor];        cell.titleString = [items objectAtIndex:indexPath.row];    }else if(indexPath.row == [items count]){        cell.backgroundColor = [UIColor blueColor];        cell.titleString = @"add";    }        return cell;}

cell的点击事件:

//cell的点击事件-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{        NSLog(@"cccc");    //判断编辑状态    if(!_isEdit){        NSMutableArray *items = [self.sectionArray objectAtIndex:indexPath.section];            if(indexPath.row == ([items count])){            [items addObject:@"abc"];            [self.collectionView reloadData];        }    }else{        NSMutableArray *items = [self.sectionArray objectAtIndex:indexPath.section];        LearnCollectionViewCell *cell = (LearnCollectionViewCell *)[collectionView cellForItemAtIndexPath:indexPath];                if(cell.selectView.hidden){            NSInteger row = indexPath.row;            if(row < [items count]){                cell.selectView.hidden = NO;                NSNumber *deleteNum = [NSNumber numberWithInteger:row];                [self.deleteCache addObject:deleteNum];            }        }else{            cell.selectView.hidden = YES;            NSInteger row = indexPath.row;            NSNumber *deleteNum = [NSNumber numberWithInteger:row];            [self.deleteCache removeObject:deleteNum];        }    }}


三.分析细节

(1)创建集合视图,3个步骤:

    1.创建布局,设置行最小间距,列最小间距。

    2.以布局类创建集合视图,设置代理

    3.注册cell,header,footer

(2)实现代理

    这里说一下这个方法

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section{    return UIEdgeInsetsMake(5, 5, 5, 5);}

   这个尺寸描述的如下图:


UIEdgeInsetsMake(5, 5, 5, 5);
这四个尺寸分别对应着途中红色的位置,它们和行间距是不同的。


四.长按移动cell位置

·iOS 9后的方法

1.添加长按手势:

    _longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressMoving:)];    [self.collectionView addGestureRecognizer:_longPress];
2.实现 dataSource 代理方法:

是否允许移动

- (BOOL)collectionView:(UICollectionView *)collectionView canMoveItemAtIndexPath:(NSIndexPath *)indexPath{    // 返回YES允许row移动    return YES;}
操作数据源

- (void)collectionView:(UICollectionView *)collectionView moveItemAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath{        NSMutableArray *items = [self.sectionArray objectAtIndex:sourceIndexPath.section];        //取出移动row数据    id item = items[sourceIndexPath.row];    //从数据源中移除该数据    [items removeObject:item];    //将数据插入到数据源中的目标位置    [items insertObject:item atIndex:destinationIndexPath.row];}

3.实现长按动作方法:

//长按cell- (void)longPressMoving:(UILongPressGestureRecognizer *)gesture{    switch (_longPress.state) {        case UIGestureRecognizerStateBegan:        {            NSIndexPath *selectIndexPath = [self.collectionView indexPathForItemAtPoint:[gesture locationInView:self.collectionView]];            LearnCollectionViewCell *cell = (LearnCollectionViewCell *)[self.collectionView cellForItemAtIndexPath:selectIndexPath];            [self.view bringSubviewToFront:cell];            [self.collectionView beginInteractiveMovementForItemAtIndexPath:selectIndexPath];        }            break;        case UIGestureRecognizerStateChanged:        {            [self.collectionView updateInteractiveMovementTargetPosition:[gesture locationInView:self.collectionView]];        }            break;        case UIGestureRecognizerStateEnded:        {            [self.collectionView endInteractiveMovement];        }            break;        default:            [self.collectionView cancelInteractiveMovement];            break;    }}


五.横向滑动,并加分页

1.需要的属性: 屏幕尺寸、页面控制、集合视图 和 相应代理

@interface ViewController ()<UICollectionViewDelegate,UICollectionViewDataSource>@property(nonatomic,strong) UICollectionView *collectionView;@property(nonatomic,strong) UIPageControl *pageControl;@property(nonatomic,assign) CGFloat screenWidth;@property(nonatomic,assign) CGFloat screenHeight;@end


2.代码
static NSString *const cellID = @"collectionCell";- (void)viewDidLoad {    [super viewDidLoad];        _screenWidth = [UIScreen mainScreen].bounds.size.width;    _screenHeight = [UIScreen mainScreen].bounds.size.height;        [self createUI];}- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{    return 1;}- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{    return 16;}-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{    UICollectionViewCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:cellID forIndexPath:indexPath];    cell.backgroundColor=[UIColor lightGrayColor];    return cell;}//cells集合四周的间隔尺寸- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section{    return UIEdgeInsetsMake(5, 5, 5, 5);} //cell尺寸- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{    return CGSizeMake((_screenWidth-40)/4, (_screenWidth-40)/4);}- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{    NSLog(@"%ld",indexPath.row);}//pagecontroll的委托方法- (void)scrollViewDidScroll:(UIScrollView *)scrollView{    int page = scrollView.contentOffset.x / scrollView.frame.size.width;    _pageControl.currentPage = page;}- (void)createUI{    //集合视图布局类    UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];    layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;    layout.minimumLineSpacing = 10;    layout.minimumInteritemSpacing = 10;        //初始化集合视图    _collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, _screenHeight-(_screenWidth-40)/2-20, _screenWidth, (_screenWidth-40)/2+20) collectionViewLayout:layout];    _collectionView.backgroundColor = [UIColor whiteColor];    _collectionView.delegate = self;    _collectionView.dataSource = self;    _collectionView.pagingEnabled = YES;    _collectionView.showsVerticalScrollIndicator = NO;    _collectionView.showsHorizontalScrollIndicator = NO;    [_collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:cellID];    [self.view addSubview:_collectionView];    _pageControl = [[UIPageControl alloc] init];    _pageControl.frame = CGRectMake(_screenWidth/2-30, _screenHeight-25, 60, 20);    _pageControl.numberOfPages = 2;    _pageControl.currentPage = 0;    _pageControl.pageIndicatorTintColor = [UIColor blueColor];    _pageControl.currentPageIndicatorTintColor = [UIColor yellowColor];    [self.view addSubview:_pageControl];}














原创粉丝点击