獲取CollectionViewCell的indexPath

最近大半個月的時間一直忙于編寫一個不大但是也不算簡單的小項目, 更新博客的頻率低了好多. 今天發(fā)現(xiàn)并解決了一個問題, 由于查找解決問題的途中發(fā)現(xiàn)很少人遇到這個問題, 覺得拿出來說說, 說不定會給以后遇到的人帶來一些便利.

首先, 頁面的需求是這樣的:

1.頁面上半部分是可以橫向分頁滾動的視圖A, 每頁顯示一個圖表
2.隨著視圖A滾動到不同的頁數(shù), 下半部分(視圖B)變換不同的數(shù)據(jù)
3.視圖A每頁的圖表有多處可以點擊,并且點擊事件也會觸發(fā)視圖B數(shù)據(jù)顯示的變換.
用圖來表示一下:


頁面要求
整體的思路并不難, 我采取了下面的方案:

1.頂部使用UICollectionView作為滾動視圖, 使其cell大小等于自身大小, 每個cell展示一個圖表
2.每次滾動完畢及點擊cell中圖表的點時, 獲取collectionView當(dāng)前展示的cell的indexPath,以此獲取該坐標(biāo)對應(yīng)的值展示到下方.

所以,這個功能的關(guān)鍵點就在于如何獲取頂部CollectionView當(dāng)前顯示的cell的indexPath.

我先后試過以下幾種方案:

方案一:

通過之前做過的自動輪播的廣告banner的經(jīng)驗(和這個需求有相似的地方),我先采用了之前的方法:
通過UICollectionView的-collectionView:didEndDisplayingCell:forItemAtIndexPath:方法得到indexPath更新的時刻, 然后用[collectionView indexPathsForVisibleItems]獲取一組當(dāng)前顯示的cell們的indexPath的數(shù)組,由于我的cell大小剛好等于collectionView的大小,所以這個數(shù)組只包含一個元素(后來證明了即使是這樣,這個數(shù)組也不一定只有一個元素),我只要取里面的第一個就好了.

- (void)collectionView:(UICollectionView *)collectionView
  didEndDisplayingCell:(UICollectionViewCell *)cell
    forItemAtIndexPath:(NSIndexPath *)indexPath {
    // 獲取當(dāng)前顯示的cell的下標(biāo)
    NSIndexPath *firstIndexPath = [[self.collectionView indexPathsForVisibleItems] firstObject];
    // 賦值給記錄當(dāng)前坐標(biāo)的變量
    self.currentIndexPath = indexPathNow;
    // 更新底部的數(shù)據(jù) 
    // ...
}

這個方案對于此頁面本身基本可以達(dá)到要求,但是由于下級頁面可能會修改到這個頁面的元素,導(dǎo)致cell個數(shù)增加或者減小, 有些情況下回到此頁面時會造成程序崩潰.
打個比方: 我的collectionView的cell共有3個,并且將cell滑動到最后一頁(最后一個cell),此時記錄當(dāng)前的下標(biāo)為2. 下級頁面刪除了一個元素,再回到此頁面的時候,didEndDisplay...方法會最先被調(diào)用,這個方法里面會取數(shù)據(jù)重新設(shè)置下半部分視圖的顯示, 而此時當(dāng)前的下標(biāo)仍為2, 數(shù)據(jù)只剩兩個了,就導(dǎo)致了應(yīng)用的崩潰.

如果從子頁面回來didEndDisplay...方法不被調(diào)用或者比較后面被調(diào)用,就不會出現(xiàn)這種情況,但是這個方法的調(diào)用時機豈是我等可以控制的? 于是乎換了一個方案.

方案二:

通過UIScrollView的-scrollViewDidEndDecelerating:方法得到indexPath更新的時刻, 然后用[collectionView indexPathsForVisibleItems]獲取一組當(dāng)前顯示的cell們的indexPath的數(shù)組,和上面的方案一樣,我只要取里面的第一個.

didEndDecelerating是在scrollView(collectionView)減速完成(滾動停止)的時刻調(diào)用的,由于又是pageEnabled == YES, 這個時刻只有一個cell在屏幕上.而且didEndDecelerating不會在從子頁面返回的時候調(diào)用,也就解決了方案一的問題.

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    // 獲取當(dāng)前顯示的cell的下標(biāo)
    NSIndexPath *firstIndexPath = [[self.collectionView indexPathsForVisibleItems] firstObject];
    // 賦值給記錄當(dāng)前坐標(biāo)的變量
    self.currentIndexPath = indexPathNow;
    // 更新底部的數(shù)據(jù) 
    // ...
}

我曾以為問題就這樣解決了,結(jié)果意外地發(fā)現(xiàn), 有些時候我點擊cell中圖表的某個點時,cell會跳變?yōu)楦舯诘腸ell,查了良久,才發(fā)現(xiàn)就是由于對collectionView當(dāng)前的坐標(biāo)獲取不準(zhǔn)確導(dǎo)致的, 進一步地發(fā)現(xiàn),這個不準(zhǔn)確就是由于:即使我的cell大小等于collectionView的大小,在[collectionView indexPathsForVisibleItems]方法得到的數(shù)組數(shù)據(jù)也有可能大于一個.并且順序還不一定,導(dǎo)致我也不能通過firstObject或者lastObject來獲取我想要的值(我也不知道為什么會大于一個還有不確定的順序).

方案三:

再后來,我找到了這個方法:indexPathForItemAtPoint:---根據(jù)某一點得到位于這點上的cell的坐標(biāo),而且返回值是一個確定的indexPath,而不是數(shù)組,正合我意.需要注意的是,這個方法傳入的參數(shù)point是以scrollView的contentView為坐標(biāo)系的坐標(biāo),使用之前要先進行一次轉(zhuǎn)換.最終我的做法是這樣:

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    // 將collectionView在控制器view的中心點轉(zhuǎn)化成collectionView上的坐標(biāo)
    CGPoint pInView = [self.view convertPoint:self.collectionView.center toView:self.collectionView];
    // 獲取這一點的indexPath
    NSIndexPath *indexPathNow = [self.collectionView indexPathForItemAtPoint:pInView];
    // 賦值給記錄當(dāng)前坐標(biāo)的變量
    self.currentIndexPath = indexPathNow;
    // 更新底部的數(shù)據(jù) 
    // ...
}

問題解決了.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末洒擦,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子补胚,更是在濱河造成了極大的恐慌干厚,老刑警劉巖让簿,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異顾腊,居然都是意外死亡危融,警方通過查閱死者的電腦和手機鞋怀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門双泪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人密似,你說我怎么就攤上這事焙矛。” “怎么了残腌?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵村斟,是天一觀的道長。 經(jīng)常有香客問我抛猫,道長蟆盹,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任闺金,我火速辦了婚禮逾滥,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘败匹。我一直安慰自己寨昙,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布掀亩。 她就那樣靜靜地躺著舔哪,像睡著了一般。 火紅的嫁衣襯著肌膚如雪槽棍。 梳的紋絲不亂的頭發(fā)上捉蚤,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天,我揣著相機與錄音炼七,去河邊找鬼外里。 笑死,一個胖子當(dāng)著我的面吹牛特石,可吹牛的內(nèi)容都是我干的盅蝗。 我是一名探鬼主播,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼姆蘸,長吁一口氣:“原來是場噩夢啊……” “哼墩莫!你這毒婦竟也來了芙委?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤狂秦,失蹤者是張志新(化名)和其女友劉穎灌侣,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體裂问,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡侧啼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了堪簿。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片痊乾。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖椭更,靈堂內(nèi)的尸體忽然破棺而出哪审,到底是詐尸還是另有隱情,我是刑警寧澤虑瀑,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布湿滓,位于F島的核電站,受9級特大地震影響舌狗,放射性物質(zhì)發(fā)生泄漏叽奥。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一痛侍、第九天 我趴在偏房一處隱蔽的房頂上張望朝氓。 院中可真熱鬧,春花似錦恋日、人聲如沸膀篮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽誓竿。三九已至,卻和暖如春谈截,著一層夾襖步出監(jiān)牢的瞬間筷屡,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工簸喂, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留毙死,地道東北人。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓喻鳄,卻偏偏與公主長得像扼倘,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫再菊、插件爪喘、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,030評論 4 62
  • 我今年24足歲,經(jīng)歷過三段感情纠拔。 第一段秉剑,在我初三那個最懵懂的時期遇到的初戀,他要的不過是我的身體稠诲; 第二段談得最...
    宅女也風(fēng)流閱讀 454評論 0 2
  • 紅燈停 綠燈行 車走人不停 菜花黃 黃花菜 春走夏不涼 人路過 過路人 相見不相識 柏油路 白馬路 道同路不同
    白芲閱讀 302評論 2 1
  • 屏幕適配 主流屏幕: 1280*720, 遵循原則: 不用AbsoluteLayout進行布局,多用相對布局,已經(jīng)...
    yanghanbin_it閱讀 162評論 0 0
  • 最近手機里不停循環(huán)播放的就是薛之謙的這首“動物世界”侦鹏。發(fā)現(xiàn)歌詞書寫的如此貼切,現(xiàn)在的社會就是弱肉強食的動物世界臀叙。誰...
    人臉大閱讀 188評論 0 0