如何能让点击cell里面的uicollectionviewcell的每一行实现跳转

11:30 提问
UICollectionView 滑动时出现内容错乱,这个重用问题怎么搞定
最近写一个东西的时候发现个问题:功能是一个collectionView使用自定义cell显示,点击每个cell相应的cell上的图片会改变。
现在有这个问题就是更换过图片以后,再上下滑动collectionView会出现下面没有选中的内容图片也会被更换,而且来回滑动的话会有很多图片都会错乱。
按赞数排序
没遇到不太清楚,不过觉得跟单元格的重用有关,最好是给单元格设置一下标识,你可以调试一下,找的问题关键点,把代码晒出来!
这个是重用必须注意的问题,系统重用一个cell,是不会帮你重置cell里面的内容,如果每次拿到一个cell后忘里面添加东西的话,在不停触发重用后,
cell里的内容就会越来越多,所以在数据源方法内应控制好updateCell的操作,每次需要往cell里添加东西时,需要将旧的remove掉,
而如果只是单纯改变cell内空间的内容(如修改cell内label的text)则不需要做这样的操作。
移除cell内旧控件的主流方法:每次updatecell往里面添加控件的时候赋值一个tag,每次update之前根据tag先把旧的控件remove
其他相似问题主题 : UICollectionViewCell上的Cell被点击后怎么实现跳转
级别: 骑士
UID: 593782
可可豆: 509 CB
威望: 457 点
在线时间: 63(时)
发自: Web Page
来源于&&分类
UICollectionViewCell上的Cell被点击后怎么实现跳转&&&
请问在CollectionViewCell里的Cell被点击了&&怎么实现跳转.&&&&等于是UICollectionView上的Cell里实现了一个CollectionViewcell&&&&
图片:cell.png
图片:cell1.png
图片:cell2.png
级别: 侠客
可可豆: 181 CB
威望: 181 点
在线时间: 521(时)
发自: Web Page
厉害了我的哥... view 里面写网络?
级别: 新手上路
UID: 492180
可可豆: 240 CB
威望: 228 点
在线时间: 397(时)
发自: Web Page
回 1楼(送你的独白) 的帖子
这个是真的有点厉害
级别: 圣骑士
UID: 515859
可可豆: 319 CB
威望: 266 点
在线时间: 432(时)
发自: Web Page
可以用代理或者block把事件抛出来,在VC里push就行了啊
级别: 骑士
UID: 543193
可可豆: 458 CB
威望: 458 点
在线时间: 331(时)
发自: Web Page
到vc里面push啊或者传个vc进去,不过这样不太好,不符合设计,好像会出现什么不好的影响。
级别: 圣骑士
UID: 595558
可可豆: 1423 CB
威望: 1167 点
在线时间: 424(时)
发自: Web Page
我是没懂为什么cell赋值的时候开GCD,然后在主线程队列中加载图片
if(life){coding++;}
级别: 精灵王
发帖: 1091
可可豆: 1198 CB
威望: 1299 点
在线时间: 1213(时)
发自: Web Page
代理啊,协议啊,通知啊,都可以解决啊,挑你喜欢的写啊,雾草面试时候的基础题啊基础题咋应用就不会了呢
级别: 圣骑士
可可豆: 643 CB
威望: 643 点
在线时间: 608(时)
发自: Web Page
给cell放图片的那些gcd代码删了吧,看着辣眼睛对于你为何在cell文件里面写了collectionview的代理方法表示很不理解你如果不太会分文件写设计模式,就全部写在viewcontroller里面好了这样就没跳转的问题了
级别: 新手上路
可可豆: 15 CB
威望: 15 点
在线时间: 31(时)
发自: Web Page
关注本帖(如果有新回复会站内信通知您)
苹果公司现任CEO是谁?2字 正确答案:库克
发帖、回帖都会得到可观的积分奖励。
按"Ctrl+Enter"直接提交
关注CocoaChina
关注微信 每日推荐
扫一扫 浏览移动版UICollectionView是从iOS6开始引入使用的,目前应用非常广泛,很牛逼!
## 与UITableView的初步比较
UITableView应该是大家最熟悉的控件了,UICollectionView的使用与之类似,但又有所区别,如下介绍。
1.都是通过datasource和delegate驱动的,因此在使用的时候必须实现数据源与代理协议方法;
2.性能上都实现了循环利用的优化。
1.UITableView的cell是系统自动布局好的,不需要我们布局。但UICollectionView的cell是需要我们自己布局的。所以我们在创建UICollectionView的时候必须传递一个布局参数,系统提供并实现了一个布局样式:流水布局(UICollectionViewFlowLayout)。
2.UITableViewController的self.view == self.,但UICollectionViewController的self.view != self.collectionView;
3.UITableView的滚动方式只能是垂直方向, UICollectionView既可以垂直滚动,也可以水平滚动;
4.UICollectionView的cell只能通过注册来确定重用标识符。
换句话说,UITableView的布局是UICollectionView的flow layout布局的一种特殊情况,类比于同矩形与正方形的关系
## 下面简单介绍几个基本用法(难度从低到高)
1. UICollectionView普通用法(FlowLayout布局)
上面我们提到了UICollectionView与UITableView的用法非常类似,下面就让我们完全根据创建UITableView的方式来创建一个UICollectionView(请读者类比UITableView的创建方式,实现数据源,代理等,这里就只提到与之不同的方面,详细代码可参考示例Demo)。
报错了,提示缺少布局参数,如下:
解决报错,我们可以传FlowLayout参数方式,也可以重写内部init方法。我们这里采用重写init方法,传递布局参数。这样更加体现了封装的思想,把传递布局参数封装在CYXNormalCollectionViewController内,对外只提供统一的外部方法:init方法,代码如下:
- (instancetype)init{
// 设置流水布局
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc]init];
// UICollectionViewFlowLayout流水布局的内部成员属性有以下:
@property (nonatomic) CGFloat minimumLineS
@property (nonatomic) CGFloat minimumInteritemS
@property (nonatomic) CGSize itemS
@property (nonatomic) CGSize estimatedItemSize NS_AVAILABLE_IOS(8_0); // defaults to CGSizeZero - setting a non-zero size enables cells that self-size via -preferredLayoutAttributesFittingAttributes:
@property (nonatomic) UICollectionViewScrollDirection scrollD // default is UICollectionViewScrollDirectionVertical
@property (nonatomic) CGSize headerReferenceS
@property (nonatomic) CGSize footerReferenceS
@property (nonatomic) UIEdgeInsets sectionI
// 定义大小
layout.itemSize = CGSizeMake(100, 100);
// 设置最小行间距
layout.minimumLineSpacing = 2;
// 设置垂直间距
layout.minimumInteritemSpacing = 2;
// 设置滚动方向(默认垂直滚动)
layout.scrollDirection = UICollectionViewScrollDirectionH
return [self initWithCollectionViewLayout:layout];
这里我们使用xib自定义cell,通过xib注册cell的代码如下
// 通过xib注册
[self.collectionView registerNib:[UINib nibWithNibName:NSStringFromClass([CYXNormalCell class]) bundle:nil] forCellWithReuseIdentifier:reuseIdentifier];
初步效果图如下(这里就不详细实现了,剩下请读者参考UITableView的用法)
2. 新手引导页制作
新手引导页,几乎是每个应用都有的,目的为了告诉用户应用的亮点,达到吸引用户的作用。
利用UICollectionView的优势(循环利用)实现新手引导页,既简单又高效,何乐而不为呢。
实现思路:
1.把UICollectionView的每个cell的尺寸设置为跟屏幕一样大;
layout.itemSize = [UIScreen mainScreen].bounds.
2.设置为水平滚动方向,设置水平间距为0.
// 设置间距
layout.minimumLineSpacing = 0;
layout.minimumInteritemSpacing = 0;
// 设置滚动方向(默认垂直滚动)
layout.scrollDirection = UICollectionViewScrollDirectionH
3.开启分页滚动模式
// 开启分页
self.collectionView.pagingEnabled = YES;
// 隐藏水平滚动条
self.collectionView.showsHorizontalScrollIndicator = NO;
// 取消弹簧效果
self.collectionView.bounces = NO;
以下是效果图:
3. 图片循环轮播器
请参考我之前的文章(内附代码)
4. 带特效的图片浏览器(自定义布局/上)
以下内容分为两小节:
1& Github例子分析
2& 自己实现一个小Demo
(1)Github例子分析
我们经常在Github上看到一些关于CollectionView的cell切换的炫酷效果,下面我们来分析一下Github上的这个
下面是效果图
目录结构分析:目录结构一目了然,关键在于有一个自动布局类(如图所示),这个类继承自UICollectionViewFlowLayout(我们可以猜到他使用的是默认的流水布局),并重写了- (void)prepareLayout、- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect等方法。我们试着把这个类里面的重载方法都注释掉,得到的效果跟普通用法的效果一样(这里就不截图了)。由此可见,作者肯定在这些方法内做了个性化的设置。
关键源码分析:
首先我们看到,作者在- (void)prepareLayout方法内做了对collectionView的初始化布局操作。因此我们可以断定重写此方法是用做初始化的(读者可以尝试修改,改变效果)。
- (void)prepareLayout
[super prepareLayout];
[self setupLayout]; // 初始化布局
- (void)setupLayout
CGFloat inset
= self.collectionView.bounds.size.width * (6/64.0f);
inset = floor(inset);
self.itemSize = CGSizeMake(self.collectionView.bounds.size.width - (2 *inset), self.collectionView.bounds.size.height * 3/4);
self.sectionInset = UIEdgeInsetsMake(0,inset, 0,inset);
self.scrollDirection = UICollectionViewScrollDirectionH
接着这个- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect方法应该是最重要的了,同理,我们先注释掉里面个性化的设置,只留[super layoutAttributesForElementsInRect:rect],我们发现炫酷的3D效果没有了。因此可以断定此方法是给每个Cell做个性化设置的。
方法解析:
这个方法的返回值是一个数组(数组里面存放着rect范围内所有元素的布局属性)
这个方法的返回值决定了rect范围内所有元素的排布方式(frame)
UICollectionViewLayoutAttributes *
1.一个cell对应一个UICollectionViewLayoutAttributes对象
2.UICollectionViewLayoutAttributes对象决定了cell的frame
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
// 获取父类(流水布局)已经计算好的布局,在这个基础上做个性化修改
NSArray *attributes = [super layoutAttributesForElementsInRect:rect];
NSArray *cellIndices = [self.collectionView indexPathsForVisibleItems];
if(cellIndices.count == 0 )
else if (cellIndices.count == 1)
mainIndexPath = cellIndices.firstO
movingInIndexPath =
else if(cellIndices.count & 1)
NSIndexPath *firstIndexPath = cellIndices.firstO
if(firstIndexPath == mainIndexPath)
movingInIndexPath = cellIndices[1];
movingInIndexPath = cellIndices.firstO
mainIndexPath = cellIndices[1];
difference =
self.collectionView.contentOffset.x - previousO
previousOffset = self.collectionView.contentOffset.x;
// 关键代码:取每一个Cell的布局属性,并添加3D效果
for (UICollectionViewLayoutAttributes *attribute in attributes)
[self applyTransformToLayoutAttributes:attribute];
上面关键方法都已经实现了,但是运行发现并没有我们想要的效果,CollectionViewCell并没有实时发生形变。y因此我们还需要调用以下方法。
方法解析:
只要滚动屏幕 就会调用 方法 -(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
只要布局页面的属性发生改变 就会重新调用 -(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect 这个方法
// indicate that we want to redraw as we scroll
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
return YES;
(2)仿写Demo
经过上面对代码的分析,我们可以简单了解到自定义layout布局的基本实现,下面就可以仿写一个简单的Demo了,效果图如下。
参考代码如下(详细见Github)
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
return YES;
- (void)prepareLayout{
[super prepareLayout];
self.scrollDirection = UICollectionViewScrollDirectionH
// 设置内边距
CGFloat inset = (self.collectionView.frame.size.width - self.itemSize.width) * 0.5;
self.sectionInset = UIEdgeInsetsMake(0, inset, 0, inset);
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
// 获得super已经计算好的布局属性
NSArray *attributes = [super layoutAttributesForElementsInRect:rect];
// 计算collectionView最中心点的x值
CGFloat centerX = self.collectionView.contentOffset.x + self.collectionView.frame.size.width * 0.5;
// 在原有布局属性的基础上,进行微调
for (UICollectionViewLayoutAttributes *attrs in attributes) {
// cell的中心点x 和 collectionView最中心点的x值 的间距
CGFloat delta = ABS(attrs.center.x - centerX);
// 根据间距值 计算 cell的缩放比例
CGFloat scale = 1.2 - delta / self.collectionView.frame.size.
NSLog(@&%f,%f&,delta,scale);
// 设置缩放比例
attrs.transform = CGAffineTransformMakeScale(scale, scale);
5.瀑布流布局(自定义布局/下)
瀑布流布局在很多应用中非常常见,效果图如下:
实现思路(简化)
(1)继承自UICollectionViewLayout;
(2)几个需要重载的方法:
- (void)prepareL
* 返回rect中的所有的元素的布局属性
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)
* 返回对应于indexPath的位置的cell的布局属性
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath;
* 返回collectionView的内容的尺寸
- (CGSize)collectionViewContentS
关键计算代码如下(详细见Github)
* 返回indexPath位置cell对应的布局属性
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
// 创建布局属性
UICollectionViewLayoutAttributes *attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
// collectionView的宽度
CGFloat collectionViewW = self.collectionView.frame.size.
// 设置布局属性的frame
CGFloat w = (collectionViewW - self.edgeInsets.left - self.edgeInsets.right - (self.columnCount - 1) * self.columnMargin) / self.columnC
CGFloat h = [self.delegate waterflowLayout:self heightForItemAtIndex:indexPath.item itemWidth:w];
// 找出高度最短的那一列
NSInteger destColumn = 0;
CGFloat minColumnHeight = [self.columnHeights[0] doubleValue];
for (NSInteger i = 1; i & self.columnC i++) {
// 取得第i列的高度
CGFloat columnHeight = [self.columnHeights[i] doubleValue];
if (minColumnHeight & columnHeight) {
minColumnHeight = columnH
destColumn =
CGFloat x = self.edgeInsets.left + destColumn * (w + self.columnMargin);
CGFloat y = minColumnH
if (y != self.edgeInsets.top) {
y += self.rowM
attrs.frame = CGRectMake(x, y, w, h);
// 更新最短那列的高度
self.columnHeights[destColumn] = @(CGRectGetMaxY(attrs.frame));
// 记录内容的高度
CGFloat columnHeight = [self.columnHeights[destColumn] doubleValue];
if (self.contentHeight & columnHeight) {
self.contentHeight = columnH
6. 布局切换
苹果已经为我们想好了布局切换的快捷方式,只需要通过以下方法,即可实现。
- (void)setCollectionViewLayout:(UICollectionViewLayout *)layout animated:(BOOL) // transition from one layout to another
- (void)setCollectionViewLayout:(UICollectionViewLayout *)layout animated:(BOOL)animated completion:(void (^ __nullable)(BOOL finished))completion NS_AVAILABLE_IOS(7_0);
阅读(...) 评论()主题 : 如何实现点击不同的CollectionViewCell,弹出的View的内容不同
级别: 新手上路
可可豆: 12 CB
威望: 12 点
在线时间: 2(时)
发自: Web Page
来源于&&分类
如何实现点击不同的CollectionViewCell,弹出的View的内容不同&&&
现在实现了点击CollectionViewCell,通过pushViewController弹出了另一个view,不过现在想要根据点击的cell的不同,来确定view的显示内容不同(一个image和一个text label)。但是发现通过setNeedsDisplay后,没有反应,而修改view的背景是可以的,修改image和text label,都不生效。请高手指教,谢谢!在新弹出的view中实现了如下方法:- (void)initContent:(int)index{&&&&self.collectionCellStore = [CollectionCellStore sharedStore];&&&&&&&&self.DetailImage.image = ((CollectionEntity*)self.collectionCellStore.cellItems[index]).&&&&self.DetailText.text = ((CollectionEntity*)self.collectionCellStore.cellItems[index]).&&&&[self.view setNeedsDisplay];}然后在cell被点击时调用:- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{&&&&DetailViewController *detailViewController = [[DetailViewController alloc] init];&&&&[detailViewController initContent:indexPath.row];&&&&&&&&[self.navigationController pushViewController:detailViewController animated:YES];&&&&}
级别: 新手上路
可可豆: 76 CB
威望: 66 点
在线时间: 454(时)
发自: Web Page
你直接在点击时把数据取出来传到新的view里面去不就可以了?何必要用index,你最终的目的不也是这个吗
级别: 新手上路
可可豆: 7 CB
威望: 7 点
在线时间: 471(时)
发自: Web Page
你就根据传过来的数据加上indexPath.row 就可以任意跳转界面了,何必那么麻烦。
级别: 新手上路
可可豆: 12 CB
威望: 12 点
在线时间: 2(时)
发自: Web Page
回 1楼(@qq.c) 的帖子
小弟就是没想出来怎么能传到弹出的view里去,新view是由xib实现的,感觉调用init方法后,再设置都不生效了,求赐教。。。
级别: 新手上路
可可豆: 12 CB
威望: 12 点
在线时间: 2(时)
发自: Web Page
回 2楼(xiaoliangge) 的帖子
不是很明白。。。能否详细说明,或者举个例子说明一下?多谢!
级别: 新手上路
可可豆: 76 CB
威望: 66 点
在线时间: 454(时)
发自: Web Page
你在新的view的.h文件中加一个数组或者一个index,用来接收当你点击时传入的数据或者index,重写set方法来设置数据,你添加或者修改数据不应该在initwithcontent方法里来做
级别: 新手上路
可可豆: 31 CB
威望: 31 点
在线时间: 30(时)
发自: Web Page
(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath 这个方法的indexpath.row就是你点击的row&&你可在这个方法里实现跳转 跳到另一个页面
关注本帖(如果有新回复会站内信通知您)
苹果公司现任CEO是谁?2字 正确答案:库克
发帖、回帖都会得到可观的积分奖励。
按"Ctrl+Enter"直接提交
关注CocoaChina
关注微信 每日推荐
扫一扫 浏览移动版

我要回帖

更多关于 uicollectionview点击 的文章

 

随机推荐