用KVO監聽實現collectionView滾動一致,完整專案movie
阿新 • • 發佈:2019-02-12
效果圖如下: 為使的上面的collectionView的滾動和下面的collectionView的滾動保持一致 先採用 kvo方式
詳情請看程式碼註釋
//1.kvo監聽模式 option需要新的值還是舊的值 [_postView addObserver:self forKeyPath:@"currentIndex" options:NSKeyValueObservingOptionNew context:nil]; [_headerColletion addObserver:self forKeyPath:@"currentIndex" options:NSKeyValueObservingOptionNew context:nil];
其中_postView 是下面的collectionView headerCollectionView是上面的collectionView 分別監聽他們的currentIndex屬性 currentIndex是標記他在第幾個item上
這裡的值得一提的事change這個這個值 可以用key new 和old取值 分別取得 新值和舊值//1.kvo監聽模式 /** keyPath:監聽的屬性名 object:監聽的物件 change:監聽的值 context:傳遞的資料 */ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { //取得新的值 NSNumber *value = [change objectForKey:@"new"]; //轉換為int值 NSInteger selectIndex = [value intValue]; //轉換為滾動到的位置書 NSIndexPath *IndexPath = [NSIndexPath indexPathForItem:selectIndex inSection:0]; //如果監聽的物件是headerView 並且postView的currentIndex 不等於headerViewcell選中的currentIndex那麼 postView 就滾動到選中的item if (object == _headerColletion && _postView.currentIndex != selectIndex) { [_postView scrollToItemAtIndexPath:IndexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:YES]; //操作完成後把postView的currentIndex 變成這個 _postView.currentIndex = selectIndex; //如果監聽的物件是postView 並且headerView的currentIndex 不等於postViewcell選中的currentIndex那麼 postView 就滾動到選中的item } else if(object == _postView && _headerColletion.currentIndex != selectIndex){ [_headerColletion scrollToItemAtIndexPath:IndexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:YES]; //操作完成後把postView的currentIndex 變成這個 _headerColletion.currentIndex = selectIndex; } }
具體可以看註釋 下面是posterView中滾動完成後的呼叫函式屬性currentIndex改變 受到監聽
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset{ //因為offset不是物件不能用點訪問 CGFloat contentX = targetContentOffset->x; /*round:如果引數是小數,則求本身的四捨五入。 ceil:如果引數是小數,則求最小的整數但不小於本身. floor:如果引數是小數,則求最大的整數但不大於本身. Example:如何值是3.4的話,則 3.4 -- round 3.000000 -- ceil 4.000000 -- floor 3.00000 **/ //用四色五入 計算第幾頁 float pageFloat = contentX/_pageWidth; NSInteger page = (int)round(pageFloat); targetContentOffset->x = page * _pageWidth; //記錄當前頁面 此處要提醒一句 這個值必須要用系統生成的setter語句來賦值才能kvo監聽 _currentIndex = page是不能夠監聽到的 self.currentIndex = page;
此處要提醒一句這個值必須要用系統生成的setter語句來賦值才能kvo監聽 _currentIndex = page是不能夠監聽到的
當點選了 不是當前的item 那麼也會滾動 currentIndex 也會改變
//單元格點選事件處理
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
//滾到點選的cell
[collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:YES];
// if ([self.scrolldelegate respondsToSelector:@selector(scrollToCurrentIndex:)]) {
// [self.scrolldelegate scrollToCurrentIndex:indexPath.item];
// }
//記錄當前的cell 此處要提醒一句 這個值必須要用系統生成的setter語句來賦值才能kvo監聽 _currentIndex = indexPath.item是不能夠監聽到的
self.currentIndex = indexPath.item;
}
其中註釋部分為代理實現方式 不用理會 如果你想看代理實現方式 可以看下一篇文章
也可以看原始碼 地址點選開啟連結 github上的動畫太卡了 真實沒那麼卡的 你們可以下下來看一下