您的位置:首页 > 产品设计 > UI/UE

UICollectView 简介(代理,数据源)

2016-12-12 09:28 246 查看
UICollectionView 和 UICollectionViewController 类是iOS6 新引进的API,用于展示集合视图,布局更加灵活,可实现多列布局,用法类似于UITableView 和 UITableViewController 类。

使用UICollectView必须实现UICollectionViewDataSource,UICollectionViewDelegate,UICollectionViewDelegateFlowLayout三个协议。

UICollectView的组成部分:跟UITableView一样,UICollectView有自己的Cell。有自己的头部视图,尾部视图(Supplementary Views)相当于UITableView的页脚和页眉。有一个用于修饰整个UICollecView的Decoration Views。



在使用UICollectView的时候必须注意的是UICollectViewLayout这个属性。该属性是UICollectView的布局属性。UICollectView跟UICollectViewLayout的关系就跟人的思想跟行为一样。思想控制一个人的行为,在这里UICollectLayout负责界定每一个cell的大小,位置等信息,UICollectView值负责每一个Cell的显示。

UICollectionViewFlowLayout(流式布局)的使用

UICollectViewLayout的子类。称线性布局或者流式布局。

其主要属性有:重点内容

//行间距
@property (nonatomic) CGFloat minimumLineSpacing;
//列间距
@property (nonatomic) CGFloat minimumInteritemSpacing;
//cell的尺寸
@property (nonatomic) CGSize itemSize;
//cell的预计尺寸
@property (nonatomic) CGSize estimatedItemSize;
//滚动的方向
@property (nonatomic) UICollectionViewScrollDirection scrollDirection;
//head的预计尺寸
@property (nonatomic) CGSize headerReferenceSize;
//footer的预计尺寸
@property (nonatomic) CGSize footerReferenceSize;
//UIdgeInsets属性
@property (nonatomic) UIEdgeInsets sectionInset;


例如:

-(void)setflowLayout
{

CGFloat itemW = 40;
CGFloat itemH = itemW * 0.8;
CGFloat itemlineMar = 5;
CGFloat itemInterMar = itemlineMar;

UICollectionViewFlowLayout * flowLayout = [[UICollectionViewFlowLayout alloc]init];

flowLayout.itemSize = CGSizeMake(itemW, itemH);
//    flowLayout.estimatedItemSize = CGSizeMake(40, 30);

flowLayout.minimumLineSpacing = itemlineMar;
flowLayout.minimumInteritemSpacing = itemInterMar;

flowLayout.footerReferenceSize = CGSizeMake(SCREEMW, 30);
flowLayout.headerReferenceSize = CGSizeMake(SCREEMW, 30);

flowLayout.sectionInset = UIEdgeInsetsMake(0, 0, 0, 0);

flowLayout.scrollDirection = UICollectionViewScrollDirectionVertical||
UICollectionViewScrollDirectionHorizontal;

flowLayout.sectionHeadersPinToVisibleBounds = YES;
flowLayout.sectionFootersPinToVisibleBounds = YES;

self.flowLayout = flowLayout;
}










UIcolllectVFlowLayout常用方法:

/**
根据indexpath设置cell的尺寸

@param collectionView 哪个UICollectView
@param collectionViewLayout 哪个布局
@param indexPath 哪个indexpath
@return 返回的尺寸
*/
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
return CGSizeMake(90, 100);
}

/**
根据section返回UIEdgeInsets

@param collectionView 哪个UICollectView
@param collectionViewLayout 哪个布局
@param section 哪个section
@return 返回的UIEdgeInsets
*/
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
{
return UIEdgeInsetsMake(0,0,0,0);
}

/**
根据section返回minimumInteritemSpacing值

@param collectionView 哪个UICollectView
@param collectionViewLayout 哪个布局
@param section 哪个section
@return 返回的minimumInteritemSpacing值
*/
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section{
return 5.0;
}

/**
根据section返回minimumInteritemSpacing值

@param collectionView 哪个UICollectView
@param collectionViewLayout 哪个布局
@param section 哪个section
@return 返回的minimumInteritemSpacing值
*/
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section{
return 10.0;
}

/**
根据section返回大概的headSize值

@param collectionView 哪个UICollectView
@param collectionViewLayout 哪个布局
@param section 哪个section
@return 返回的headSize值
*/
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section{
return CGSizeMake(SCREEMW, 40);
}

/**
根据section放回大概的footerSize值

@param collectionView 哪个UICollectView
@param collectionViewLayout 哪个布局
@param section 哪个section
@return 返回的footerSize值
*/
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section{
return CGSizeMake(SCREEMW, 40);
}


以上方法不一定要实现,根据需要选择需要的api即可。

UICollectionViewDelegate的使用

与UITabelView类似,UICollectView有自己的代理与数据源(UICollectionViewDataSource)方法。

**UICollectView常见属性:*

//布局属性
@property (nonatomic, strong) UICollectionViewLayout *collectionViewLayout;
//代理
@property (nonatomic, weak, nullable) id <UICollectionViewDelegate> delegate;
//数据源
@property (nonatomic, weak, nullable) id <UICollectionViewDataSource> dataSource;

//设置是否允许选中 默认yes
@property (nonatomic) BOOL allowsSelection;

//设置是否允许多选 默认no
@property (nonatomic) BOOL allowsMultipleSelection;


若需要深究UICollectView属性,建议学习一下它的prefetchDataSource(预数据源方法)

UICollectionView的常见方法:

⚠️:在完成UICollection的代理事件之前一定要实现一下一个注册cell的函数,不然会崩溃。

//设置选中某一item,并使视图滑动到相应位置,scrollPosition是滑动位置的相关参数,如下:
/*
typedef NS_OPTIONS(NSUInteger, UICollectionViewScrollPosition) {
//无
UICollectionViewScrollPositionNone                 = 0,
//垂直布局时使用的 对应上中下
UICollectionViewScrollPositionTop                  = 1 << 0,
UICollectionViewScrollPositionCenteredVertically   = 1 << 1,
UICollectionViewScrollPositionBottom               = 1 << 2,
//水平布局时使用的
e8cd
对应左中右
UICollectionViewScrollPositionLeft                 = 1 << 3,
UICollectionViewScrollPositionCenteredHorizontally = 1 << 4,
UICollectionViewScrollPositionRight                = 1 << 5
};
*/
- (void)selectItemAtIndexPath:(nullable NSIndexPath *)indexPath animated:(BOOL)animated scrollPosition:(UICollectionViewScrollPosition)scrollPosition;

//将某一item取消选中
- (void)deselectItemAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated;

//重新加载数据
- (void)reloadData;

//下面这两个方法,可以重新设置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);

//下面这些方法更加强大,我们可以对布局更改后的动画进行设置
//这个方法传入一个布局策略layout,系统会开始进行布局渲染,返回一个UICollectionViewTransitionLayout对象
//这个UICollectionViewTransitionLayout对象管理动画的相关属性,我们可以进行设置
- (UICollectionViewTransitionLayout *)startInteractiveTransitionToCollectionViewLayout:(UICollectionViewLayout *)layout completion:(nullable UICollectionViewLayoutInteractiveTransitionCompletion)completion NS_AVAILABLE_IOS(7_0);
//准备好动画设置后,我们需要调用下面的方法进行布局动画的展示,之后会调用上面方法的block回调
- (void)finishInteractiveTransition NS_AVAILABLE_IOS(7_0);
//调用这个方法取消上面的布局动画设置,之后也会进行上面方法的block回调
- (void)cancelInteractiveTransition NS_AVAILABLE_IOS(7_0);

//获取分区数
- (NSInteger)numberOfSections;

//获取某一分区的item数
- (NSInteger)numberOfItemsInSection:(NSInteger)section;

//下面两个方法获取item或者头尾视图的layout属性,这个UICollectionViewLayoutAttributes对象
//存放着布局的相关数据,可以用来做完全自定义布局,后面博客会介绍
- (nullable UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath;
- (nullable UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath;

//获取某一点所在的indexpath位置
- (nullable NSIndexPath *)indexPathForItemAtPoint:(CGPoint)point;

//获取某个cell所在的indexPath
- (nullable NSIndexPath *)indexPathForCell:(UICollectionViewCell *)cell;

//根据indexPath获取cell
- (nullable UICollectionViewCell *)cellForItemAtIndexPath:(NSIndexPath *)indexPath;

//获取所有可见cell的数组
- (NSArray<__kindof UICollectionViewCell *> *)visibleCells;

//获取所有可见cell的位置数组
- (NSArray<NSIndexPath *> *)indexPathsForVisibleItems;

//下面三个方法是iOS9中新添加的方法,用于获取头尾视图
- (UICollectionReusableView *)supplementaryViewForElementKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(9_0);
- (NSArray<UICollectionReusableView *> *)visibleSupplementaryViewsOfKind:(NSString *)elementKind NS_AVAILABLE_IOS(9_0);
- (NSArray<NSIndexPath *> *)indexPathsForVisibleSupplementaryElementsOfKind:(NSString *)elementKind NS_AVAILABLE_IOS(9_0);

//使视图滑动到某一位置,可以带动画效果
- (void)scrollToItemAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UICollectionViewScrollPosition)scrollPosition animated:(BOOL)animated;

//下面这些方法用于动态添加,删除,移动某些分区获取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;

/**
UICollectView注册一个定义好的cell(拿出来单独写的目的是将注册函数独立出来)
// If a class is registered, it will be instantiated via alloc/initWithFrame:
@param cellClass 哪个class
@param identifier 重用标识
*/
- (void)registerClass:(nullable Class)cellClass forCellWithReuseIdentifier:(NSString *)identifier{
[self.collectView registerClass:cellClass forCellWithReuseIdentifier:identifier];
}

/**
UICollectView注册一个定义好的cell(拿出来单独写的目的是将注册函数独立出来)
// If a nib is registered, it must contain exactly 1 top level object which is a UICollectionViewCell.
@param nib 哪个nib文件
@param identifier 重用标识
*/
- (void)registerNib:(nullable UINib *)nib forCellWithReuseIdentifier:(NSString *)identifier
{
[self registerNib:nib forCellWithReuseIdentifier:identifier];
}

/**
Class注册SupplementaryView

@param viewClass class
@param elementKind <#elementKind description#>
@param identifier <#identifier description#>
*/
- (void)registerClass:(nullable Class)viewClass forSupplementaryViewOfKind:(NSString *)elementKind withReuseIdentifier:(NSString *)identifier{

}

/**
NIB注册SupplementaryView

@param nib NIB
@param kind <#kind description#>
@param identifier <#identifier description#>
*/
- (void)registerNib:(nullable UINib *)nib forSupplementaryViewOfKind:(NSString *)kind withReuseIdentifier:(NSString *)identifier{

}

/**
跟UITableView的cell重用机制一样
@param identifier <#identifier description#>
@param indexPath <#indexPath description#>
@return <#return value description#>
*/
- (__kindof UICollectionViewCell *)dequeueReusableCellWithReuseIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath{

}

/**
重用SupplementaryView

@param elementKind <#elementKind description#>
@param identifier <#identifier description#>
@param indexPath <#indexPath description#>
@return <#return value description#>
*/
- (__kindof UICollectionReusableView *)dequeueReusableSupplementaryViewOfKind:(NSString *)elementKind withReuseIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath{

}


例如:重点内容

//注册Cell,必须要有
[self registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"UICollectionViewCell"];


UICollectionViewDelegate的常用方法:

其中的需要事项的方法与UITableViewdelegate中的基本一样:

/**
是否允许cell被选择的时候高亮

@param collectionView 哪个UICollectionView
@param indexPath 哪个indexPath
@return YES OR NO
*/
- (BOOL)collectionView:(UICollectionView *)collectionView shouldHighlightItemAtIndexPath:(NSIndexPath *)indexPath{}

/**
cell已经高亮做什么

@param collectionView 哪个UICollectView
@param indexPath 哪个indexPath
*/
- (void)collectionView:(UICollectionView *)collectionView didHighlightItemAtIndexPath:(NSIndexPath *)indexPath{}

/**
失去高亮做什么

@param collectionView 哪个UICollecView
@param indexPath 哪个indexpath
*/
- (void)collectionView:(UICollectionView *)collectionView didUnhighlightItemAtIndexPath:(NSIndexPath *)indexPath{}

/**
cell是否能被选择默认允许

@param collectionView 哪个UICollectView
@param indexPath 哪个indexpath
@return YES OR NO
*/
- (BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath{}

/**
是否允许失去选择默认允许

@param collectionView 哪个UICollectView
@param indexPath 哪个indexpath
@return YES or NO
*/
- (BOOL)collectionView:(UICollectionView *)collectionView shouldDeselectItemAtIndexPath:(NSIndexPath *)indexPath{}

// called when the user taps on an already-selected item in multi-select mode

/**
当cell被选择的时候调用

@param collectionView 哪个UICollectView
@param indexPath 哪个indexpath
*/
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{}

/**
失去选择的时候做什么

@param collectionView 哪个UICollectView
@param indexPath 哪个indexpath
*/
- (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath{}

/**
cell即将被显示出来的时候调用

@param collectionView 哪个UICollectView
@param cell 哪个Cell
@param indexPath 哪个indexpath
*/
- (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath{}

/**
cell完成显示的时候调用

@param collectionView 哪个UICollectView
@param cell 哪个cell
@param indexPath 哪个indexPath
*/
- (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath{}

/**
SupplementaryView即将被显示的时候调用

@param collectionView 哪个UICollectView
@param view 哪个SupplementaryView
@param elementKind 哪个元素
@param indexPath 哪个indexpath
*/
- (void)collectionView:(UICollectionView *)collectionView willDisplaySupplementaryView:(UICollectionReusableView *)view forElementKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath{}

/**
SupplementaryView完成显示的时候调用

@param collectionView 哪个UICollectView
@param view 哪个SupplementaryView
@param elementKind 哪个元素
@param indexPath 哪个indexpath
*/
- (void)collectionView:(UICollectionView *)collectionView didEndDisplayingSupplementaryView:(UICollectionReusableView *)view forElementOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath{}

/**
是否显示编辑菜单(如复制,粘贴等)

@param collectionView 哪个UICollectView
@param indexPath 哪个indexpath
@return YES or NO
*/
- (BOOL)collectionView:(UICollectionView *)collectionView shouldShowMenuForItemAtIndexPath:(NSIndexPath *)indexPath{}

/**
菜单中哪些编辑操作可以显示

@param collectionView 哪个UICollectView
@param action 哪个编辑行为
@param indexPath 哪个indexpath
@param sender 哪个发送者
@return YES or NO
*/
- (BOOL)collectionView:(UICollectionView *)collectionView canPerformAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(nullable id)sender{
NSLog(@"%@",NSStringFromSelector(action));
if (action == @selector(copy:)){
return YES;   //此处只显示copy
}
return NO;
}

/**
//对于显示的编辑操作怎么执行

@param collectionView 哪个UICollectView
@param action 哪个行为
@param indexPath 哪个indexpath
@param sender 哪个发送者
*/
- (void)collectionView:(UICollectionView *)collectionView performAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(nullable id)sender{

if (action == @selector(copy:)){
MyUICollectionViewCell *cell = (MyUICollectionViewCell )[collectionView  cellForItemAtIndexPath:indexPath];
[[UIPasteboard generalPasteboard] setImage:cell.Icon.ima.image];    //剪贴板存储
}

}


UICollectionViewDataSource常用方法重点内容

这/**
设置section的rows

@param collectionView 哪个UICollecView
@param section 哪个section
@return 返回的rows
*/
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{}

/**
设置cell的neirong

@param collectionView 哪个UICollectView
@param indexPath 哪个indexPath
@return 返回的cell
*/
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath;

/**
设置sections数量

@param collectionView 哪个UICollecView
@return 返回的sectiins
*/
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView;

/**
设置SupplementaryView

// The view that is returned must be retrieved from a call to -dequeueReusableSupplementaryViewOfKind:withReuseIdentifier:forIndexPath:

@param collectionView 哪个UICollectView
@param kind 哪个元素
@param indexPath 哪个indexpath
@return 返回的SupplementaryView
*/
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath;

/**
cell是否能勾移动

@param collectionView 哪个UICollectView
@param indexPath 哪个indexpath
@return YES or NO
*/
- (BOOL)collectionView:(UICollectionView *)collectionView canMoveItemAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(9_0);

/**
cell移动的时候调用
在此操作数据
@param collectionView 哪个UICollectView
@param sourceIndexPath 开始indexpath
@param destinationIndexPath 目标indexpath
*/
- (void)collectionView:(UICollectionView *)collectionView moveItemAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath*)destinationIndexPath NS_AVAILABLE_IOS(9_0);里写代码片
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  UICollectV ios 布局