获取CollectionViewCell的indexPath

最近大半个月的时间一直忙于编写一个不大但是也不算简单的小项目, 更新博客的频率低了好多. 今天发现并解决了一个问题, 由于查找解决问题的途中发现很少人遇到这个问题, 觉得拿出来说说, 说不定会给以后遇到的人带来一些便利.

首先, 页面的需求是这样的:

1.页面上半部分是可以横向分页滚动的视图A, 每页显示一个图表
2.随着视图A滚动到不同的页数, 下半部分(视图B)变换不同的数据
3.视图A每页的图表有多处可以点击,并且点击事件也会触发视图B数据显示的变换.
用图来表示一下:


页面要求
整体的思路并不难, 我采取了下面的方案:

1.顶部使用UICollectionView作为滚动视图, 使其cell大小等于自身大小, 每个cell展示一个图表
2.每次滚动完毕及点击cell中图表的点时, 获取collectionView当前展示的cell的indexPath,以此获取该坐标对应的值展示到下方.

所以,这个功能的关键点就在于如何获取顶部CollectionView当前显示的cell的indexPath.

我先后试过以下几种方案:

方案一:

通过之前做过的自动轮播的广告banner的经验(和这个需求有相似的地方),我先采用了之前的方法:
通过UICollectionView的-collectionView:didEndDisplayingCell:forItemAtIndexPath:方法得到indexPath更新的时刻, 然后用[collectionView indexPathsForVisibleItems]获取一组当前显示的cell们的indexPath的数组,由于我的cell大小刚好等于collectionView的大小,所以这个数组只包含一个元素(后来证明了即使是这样,这个数组也不一定只有一个元素),我只要取里面的第一个就好了.

- (void)collectionView:(UICollectionView *)collectionView
  didEndDisplayingCell:(UICollectionViewCell *)cell
    forItemAtIndexPath:(NSIndexPath *)indexPath {
    // 获取当前显示的cell的下标
    NSIndexPath *firstIndexPath = [[self.collectionView indexPathsForVisibleItems] firstObject];
    // 赋值给记录当前坐标的变量
    self.currentIndexPath = indexPathNow;
    // 更新底部的数据 
    // ...
}

这个方案对于此页面本身基本可以达到要求,但是由于下级页面可能会修改到这个页面的元素,导致cell个数增加或者减小, 有些情况下回到此页面时会造成程序崩溃.
打个比方: 我的collectionView的cell共有3个,并且将cell滑动到最后一页(最后一个cell),此时记录当前的下标为2. 下级页面删除了一个元素,再回到此页面的时候,didEndDisplay...方法会最先被调用,这个方法里面会取数据重新设置下半部分视图的显示, 而此时当前的下标仍为2, 数据只剩两个了,就导致了应用的崩溃.

如果从子页面回来didEndDisplay...方法不被调用或者比较后面被调用,就不会出现这种情况,但是这个方法的调用时机岂是我等可以控制的? 于是乎换了一个方案.

方案二:

通过UIScrollView的-scrollViewDidEndDecelerating:方法得到indexPath更新的时刻, 然后用[collectionView indexPathsForVisibleItems]获取一组当前显示的cell们的indexPath的数组,和上面的方案一样,我只要取里面的第一个.

didEndDecelerating是在scrollView(collectionView)减速完成(滚动停止)的时刻调用的,由于又是pageEnabled == YES, 这个时刻只有一个cell在屏幕上.而且didEndDecelerating不会在从子页面返回的时候调用,也就解决了方案一的问题.

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    // 获取当前显示的cell的下标
    NSIndexPath *firstIndexPath = [[self.collectionView indexPathsForVisibleItems] firstObject];
    // 赋值给记录当前坐标的变量
    self.currentIndexPath = indexPathNow;
    // 更新底部的数据 
    // ...
}

我曾以为问题就这样解决了,结果意外地发现, 有些时候我点击cell中图表的某个点时,cell会跳变为隔壁的cell,查了良久,才发现就是由于对collectionView当前的坐标获取不准确导致的, 进一步地发现,这个不准确就是由于:即使我的cell大小等于collectionView的大小,在[collectionView indexPathsForVisibleItems]方法得到的数组数据也有可能大于一个.并且顺序还不一定,导致我也不能通过firstObject或者lastObject来获取我想要的值(我也不知道为什么会大于一个还有不确定的顺序).

方案三:

再后来,我找到了这个方法:indexPathForItemAtPoint:---根据某一点得到位于这点上的cell的坐标,而且返回值是一个确定的indexPath,而不是数组,正合我意.需要注意的是,这个方法传入的参数point是以scrollView的contentView为坐标系的坐标,使用之前要先进行一次转换.最终我的做法是这样:

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    // 将collectionView在控制器view的中心点转化成collectionView上的坐标
    CGPoint pInView = [self.view convertPoint:self.collectionView.center toView:self.collectionView];
    // 获取这一点的indexPath
    NSIndexPath *indexPathNow = [self.collectionView indexPathForItemAtPoint:pInView];
    // 赋值给记录当前坐标的变量
    self.currentIndexPath = indexPathNow;
    // 更新底部的数据 
    // ...
}

问题解决了.

最后编辑于
?著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,029评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,238评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事?!?“怎么了?”我有些...
    开封第一讲书人阅读 159,576评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,214评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,324评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,392评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,416评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,196评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,631评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,919评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,090评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,767评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,410评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,090评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,328评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,952评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,979评论 2 351

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,079评论 4 62
  • 我今年24足岁,经历过三段感情。 第一段,在我初三那个最懵懂的时期遇到的初恋,他要的不过是我的身体; 第二段谈得最...
    宅女也风流阅读 460评论 0 2
  • 红灯停 绿灯行 车走人不停 菜花黄 黄花菜 春走夏不凉 人路过 过路人 相见不相识 柏油路 白马路 道同路不同
    白芲阅读 304评论 2 1
  • 屏幕适配 主流屏幕: 1280*720, 遵循原则: 不用AbsoluteLayout进行布局,多用相对布局,已经...
    yanghanbin_it阅读 163评论 0 0
  • 最近手机里不停循环播放的就是薛之谦的这首“动物世界”。发现歌词书写的如此贴切,现在的社会就是弱肉强食的动物世界。谁...
    人脸大阅读 192评论 0 0