前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >iOS流布局UICollectionView系列一——初识与简单使用UICollectionView

iOS流布局UICollectionView系列一——初识与简单使用UICollectionView

作者头像
珲少
发布于 2018-08-16 06:30:57
发布于 2018-08-16 06:30:57
3.3K00
代码可运行
举报
文章被收录于专栏:一“技”之长一“技”之长
运行总次数:0
代码可运行

iOS流布局UICollectionView系列一——初识与简单使用UICollectionView

一、简介

        UICollectionView是iOS6之后引入的一个新的UI控件,它和UITableView有着诸多的相似之处,其中许多代理方法都十分类似。简单来说,UICollectionView是比UITbleView更加强大的一个UI控件,有如下几个方面:

1、支持水平和垂直两种方向的布局

2、通过layout配置方式进行布局

3、类似于TableView中的cell特性外,CollectionView中的Item大小和位置可以自由定义

4、通过layout布局回调的代理方法,可以动态的定制每个item的大小和collection的大体布局属性

5、更加强大一点,完全自定义一套layout布局方案,可以实现意想不到的效果

这篇博客,我们主要讨论CollectionView使用原生layout的方法和相关属性,其他特点和更强的制定化,会在后面的博客中介绍

二、先来实现一个最简单的九宫格类布局

        在了解UICollectionView的更多属性前,我们先来使用其进行一个最简单的流布局试试看,在controller的viewDidLoad中添加如下代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    //创建一个layout布局类
    UICollectionViewFlowLayout * layout = [[UICollectionViewFlowLayout alloc]init];
    //设置布局方向为垂直流布局
    layout.scrollDirection = UICollectionViewScrollDirectionVertical;
    //设置每个item的大小为100*100
    layout.itemSize = CGSizeMake(100, 100);
    //创建collectionView 通过一个布局策略layout来创建
    UICollectionView * collect = [[UICollectionView alloc]initWithFrame:self.view.frame collectionViewLayout:layout];
    //代理设置
    collect.delegate=self;
    collect.dataSource=self;
    //注册item类型 这里使用系统的类型
    [collect registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"cellid"];
   
    [self.view addSubview:collect];

这里有一点需要注意,collectionView在完成代理回调前,必须注册一个cell,类似如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[collect registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"cellid"];

这和tableView有些类似,又有些不同,因为tableView除了注册cell的方法外,还可以通过临时创建来做:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//tableView在从复用池中取cell的时候,有如下两种方法
//使用这种方式如果复用池中无,是可以返回nil的,我们在临时创建即可
- (nullable __kindof UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier;
//6.0后使用如下的方法直接从注册的cell类获取创建,如果没有注册 会崩溃
- (__kindof UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(6_0);

我们可以分析:因为UICollectionView是iOS6.0之前的新类,因此这里统一了从复用池中获取cell的方法,没有再提供可以返回nil的方式,并且在UICollectionView的回调代理中,只能使用从复用池中获取cell的方式进行cell的返回,其他方式会崩溃,例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//这是正确的方法
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
    UICollectionViewCell * cell  = [collectionView dequeueReusableCellWithReuseIdentifier:@"cellid" forIndexPath:indexPath];
    cell.backgroundColor = [UIColor colorWithRed:arc4random()%255/255.0 green:arc4random()%255/255.0 blue:arc4random()%255/255.0 alpha:1];
    return cell;
}

//这样做会崩溃
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
//    UICollectionViewCell * cell  = [collectionView dequeueReusableCellWithReuseIdentifier:@"cellid" forIndexPath:indexPath];
//    cell.backgroundColor = [UIColor colorWithRed:arc4random()%255/255.0 green:arc4random()%255/255.0 blue:arc4random()%255/255.0 alpha:1];
    UICollectionViewCell * cell = [[UICollectionViewCell alloc]init];
    return cell;
}

上面错误的方式会崩溃,信息如下,让我们使用从复用池中取cell的方式:

上面的设置完成后,我们来实现如下几个代理方法:

这里与TableView的回调方式十分类似

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//返回分区个数
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
    return 1;
}
//返回每个分区的item个数
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
    return 10;
}
//返回每个item
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
    UICollectionViewCell * cell  = [collectionView dequeueReusableCellWithReuseIdentifier:@"cellid" forIndexPath:indexPath];
    cell.backgroundColor = [UIColor colorWithRed:arc4random()%255/255.0 green:arc4random()%255/255.0 blue:arc4random()%255/255.0 alpha:1];
    return cell;
}

效果如下:

同样,如果内容的大小超出一屏,和tableView类似是可以进行视图滑动的。

还有一点细节,我们在上面设置布局方式的时候设置了垂直布局:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
layout.scrollDirection = UICollectionViewScrollDirectionVertical;
//这个是水平布局
//layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;

这样系统会在一行充满后进行第二行的排列,如果设置为水平布局,则会在一列充满后,进行第二列的布局,这种方式也被称为流式布局

三、UICollectionView中的常用方法和属性

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//通过一个布局策略初识化CollectionView
- (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout;

//获取和设置collection的layout
@property (nonatomic, strong) UICollectionViewLayout *collectionViewLayout;

//数据源和代理
@property (nonatomic, weak, nullable) id <UICollectionViewDelegate> delegate;
@property (nonatomic, weak, nullable) id <UICollectionViewDataSource> dataSource;

//从一个class或者xib文件进行cell(item)的注册
- (void)registerClass:(nullable Class)cellClass forCellWithReuseIdentifier:(NSString *)identifier;
- (void)registerNib:(nullable UINib *)nib forCellWithReuseIdentifier:(NSString *)identifier;

//下面两个方法与上面相似,这里注册的是头视图或者尾视图的类
//其中第二个参数是设置 头视图或者尾视图 系统为我们定义好了这两个字符串
//UIKIT_EXTERN NSString *const UICollectionElementKindSectionHeader NS_AVAILABLE_IOS(6_0);
//UIKIT_EXTERN NSString *const UICollectionElementKindSectionFooter NS_AVAILABLE_IOS(6_0);
- (void)registerClass:(nullable Class)viewClass forSupplementaryViewOfKind:(NSString *)elementKind withReuseIdentifier:(NSString *)identifier;
- (void)registerNib:(nullable UINib *)nib forSupplementaryViewOfKind:(NSString *)kind withReuseIdentifier:(NSString *)identifier;

//这两个方法是从复用池中取出cell或者头尾视图
- (__kindof UICollectionViewCell *)dequeueReusableCellWithReuseIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath;
- (__kindof UICollectionReusableView *)dequeueReusableSupplementaryViewOfKind:(NSString *)elementKind withReuseIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath;

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

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

//获取所有选中的item的位置信息
- (nullable NSArray<NSIndexPath *> *)indexPathsForSelectedItems; 

//设置选中某一item,并使视图滑动到相应位置,scrollPosition是滑动位置的相关参数,如下:
/*
typedef NS_OPTIONS(NSUInteger, UICollectionViewScrollPosition) {
    //无
    UICollectionViewScrollPositionNone                 = 0,
    //垂直布局时使用的 对应上中下
    UICollectionViewScrollPositionTop                  = 1 << 0,
    UICollectionViewScrollPositionCenteredVertically   = 1 << 1,
    UICollectionViewScrollPositionBottom               = 1 << 2,
    //水平布局时使用的  对应左中右
    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;

专注技术,热爱生活,交流技术,也做朋友。 ——珲少 QQ群:203317592

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2015/10/27 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
纯css实现117个Loading效果(上)
这是我这几十年间从世界各地寻觅到的 Loading特效,合计117个(本文贴出第1-39个),而且是 纯CSS 制作的。
德育处主任
2022/04/15
2.8K0
纯css实现117个Loading效果(上)
纯css实现117个Loading效果(中)
这是我这几十年间从世界各地寻觅到的 Loading特效,合计117个(本文贴出第40-78个),而且是 纯CSS 制作的。
德育处主任
2022/04/17
1.4K0
纯css实现117个Loading效果(中)
仅用 CSS 实现赛博朋克 2077 风格视觉效果
《赛博朋克2077》 是一款动作角色类游戏,于 2020年12月10日 登陆各大游戏平台。故事发生在夜之城,权力更迭和身体改造是这里不变的主题。玩家将扮演一名野心勃勃的雇佣兵:V,追寻一种独一无二的植入体——获得永生的关键。它以自由的探索性,较高的操控度以及惊艳的视觉特效收获了一大批玩家。我非常喜欢 2077 官网的设计风格,因此本篇文章主要以 2077 官网为例,通过几个例子,依次实现赛博朋克风格元素效果。
zz_jesse
2021/07/30
5950
纯CSS3实现loading虚影加载效果
从效果而言,我们主要实现下列步骤: 1、让一个圆旋转,并且是先快后慢; 2、有颜色过渡效果、并且有透明度; 3、然后就是复制上面的效果,5个,然后按时间执行动画
Javanx
2019/09/04
1K0
纯CSS3实现loading虚影加载效果
原来404页面也能这么炫酷!
在浏览网页的时候,经常会遇到一些404的网页,一般来说都是很简陋的布局,但是最近发现了一个超炫酷的404页面,自己也学着做了一个,下面一起来学习一下怎么制作吧!
小丞同学
2021/08/16
8521
【前端攻略--HTML/CSS】这是你需要的transform学习教程
transition语法格式:transition: property duration timing-function delay;
野原测试开发
2019/07/10
1K0
深藏在CSS里的诗情画意(十个原创的CSS特效,不容错过)
很多的碎碎念都用都用 HTML 跟 CSS 来记录在我的codepen https://codepen.io/krischan77 之上,眼见积累到了一些了,就选出几个来与大家一同分享。
陈大鱼头
2020/04/16
7880
深藏在CSS里的诗情画意(十个原创的CSS特效,不容错过)
搞定这些疑难杂症,向css3动画说yes
本文篇幅比较长,涉及到的知识点也比较多,如3d,动画性能,动画js事件等,参考文献及demo展示也比较多,所以建议pc阅读效果更佳。 动画库 到现在来说css3动画也不是什么新技术,既然是要搞定它,好歹我们也得先看下别人做的一些东西吧,所以在此先向各位推荐几个比较好用的动画库: animate.css effeckt hover.css animatable 关于css3动画不得不说的几个属性 看完上面那些动画库,心痒就不如行动了。 说起css3动画,有一个属性我们绝对避不开了,那就是transform这个
IMWeb前端团队
2018/01/15
2.1K0
搞定这些疑难杂症,向css3动画说yes
html下划线 下移,css如何实现下划线滑动效果
本文主要讲述两种下划线动效效果,第一种悬停时X轴由内向外展开实现动画效果,第二种为左右自动展示,由左向右,或由右向左。
全栈程序员站长
2022/09/03
2.2K0
html下划线 下移,css如何实现下划线滑动效果
天哪!跟真的一样(CSS)
  无论是css还是别的,前端的学习总是妙趣横生,只要思想在不断进步,技术就会一次次的突破。如果你学习过CSS,你会更加了解这段代码的神奇,送给你,远道而来的求学者。   如果你不曾学习过CSS,又想将代码保存下来,留待将来学习和参悟,那么请点击 “ 这里 ” ,一遍就能学废。
我不是费圆
2020/09/21
9400
天哪!跟真的一样(CSS)
SAO-UI-PLAN--Card-Player
这是SAO UI PLAN 的第五弹了,效果没有我想的那么理想。在面积有限的作者卡片上做文章实在是有些捉襟见肘,除了可以在配色上动动脑筋以外,没啥可以放内容的地方。
Akilar
2021/08/03
8640
奇思妙想 CSS 文字动画
本文将会和这篇 -- CSS 奇思妙想边框动画类似,讲一些文字效果,利用不同的属性搭配,实现各式各样的文字动效。
Sb_Coco
2021/03/11
3.5K0
奇思妙想 CSS 文字动画
仅用一个HTML标签,实现带动画的抖音LOGO
大家好,我是零一,今天给大家表演 仅用一个HTML标签实现带动画的抖音LOGO,涉及了很多知识点,欢迎交流讨论
@零一
2022/04/26
1.3K0
仅用一个HTML标签,实现带动画的抖音LOGO
分享三款好看的文字特效
一、抖音故障艺术效果 1、引用CSS.tiktok{ text-shadow: -2px 0 rgba(0, 255, 255, .5), 2px 0 rgba(255, 0, 0, .5); animation: shake-it .5s reverse infinite cubic-bezier(0.68, -0.55, 0.27, 1.55);}@keyframes shake-it{ 0%{ text-shadow: 0 0 rgba(0, 255, 255,
小何.
2023/03/03
1.2K0
CSS八种让人眼前一亮的HOVER效果
巧用伪元素:before、:after等,让你的页面按钮眼前一亮。原文链接:8 amazing HTML button hover effects, that will make your website memorable。更多内容:github.com/reng99/blog…
Jimmy_is_jimmy
2020/10/15
8530
css3动画从入门到精通
什么是css3动画? 通过 CSS3,我们能够创建动画,这可以在许多网页中取代动画图片、Flash 动画以及 JavaScript。 CSS3带来了圆角,半透明,阴影,渐变,多背景图等新的特征,轻松实
xiangzhihong
2018/02/05
2.5K0
css3动画从入门到精通
CSS3 动画 animation
复习下 css3 的动画, 都快不会写了,那会儿挺喜欢 flash 的,可惜了时代在前进。写这里就当是文档看吧
chuchur
2022/10/25
5300
CSS3 动画 animation
CSS3的transition动画功能
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>transition动画效果</title> <style> body{ background-color: rgba(163, 207, 255, 0.69); } a:link{ color: #ff5ee6; }
xing.org1^
2018/05/17
8870
一颗红心,三手准备,分别基于图片(img)/SCSS(样式)/SVG动画实现动态拉轰的点赞按钮特效
    华丽炫酷的动画特效总能够让人心旷神怡,不能自已。艳羡之余,如果还能够探究其华丽外表下的实现逻辑,那就是百尺竿头,更上一步了。本次我们使用图片、SCSS样式以及SVG图片动画来实现“点赞”按钮的动画特效,并比较不同之处。
用户9127725
2022/09/28
1.4K0
一颗红心,三手准备,分别基于图片(img)/SCSS(样式)/SVG动画实现动态拉轰的点赞按钮特效
Vue-transition组件的Css动画+过渡(1)入门,笔记总结 “建议收藏”
这里说一下transition: property duration timing-function delay; 一共有四个参数可选;
玖柒的小窝
2021/09/29
1.5K0
相关推荐
纯css实现117个Loading效果(上)
更多 >
LV.1
普联软件前端开发工程师
目录
  • iOS流布局UICollectionView系列一——初识与简单使用UICollectionView
    • 一、简介
    • 二、先来实现一个最简单的九宫格类布局
    • 三、UICollectionView中的常用方法和属性
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档