2015-11-10 33 views
2

我有一個水平流佈局和固定寬度單元格的集合視圖。當用戶結束拖動時,我想要在獲取減速結束時可見的的項目的內容時獲得先行開頭。當滾動視圖didEndDragging時,預測可見的索引路徑

爲此,我需要在減速結束時可見的索引路徑。我認爲此代碼的工作,但是是跛腳(出於顯而易見的原因,我認爲,只有幾個人在註釋中描述):

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset { 
    // already bummed here: 
    // a) this seems the wrong way to get the fixed cell width 
    // b) sad that this method precludes variable width cells 
    UICollectionViewLayoutAttributes *la = [self.collectionView.collectionViewLayout layoutAttributesForElementsInRect:self.collectionView.bounds][0]; 
    CGFloat width = la.size.width; 

    // this must be wrong, too. what about insets, header views, etc? 
    NSInteger firstVisible = floorf(targetContentOffset->x/width); 

    NSInteger visibleCount = ceilf(self.collectionView.bounds.size.width/width); 
    NSInteger lastVisible = MIN(firstVisible+visibleCount, self.model.count); 
    NSMutableArray *willBeVisibleIndexPaths = [@[] mutableCopy]; 

    // neglecting sections 
    for (NSInteger i=firstVisible; i<lastVisible; i++) { 
     [willBeVisibleIndexPaths addObject:[NSIndexPath indexPathForItem:i inSection:0]]; 
    } 
} 

這是一個很大的脆弱的代碼做一些事情,似乎是直接的。如果我想要它處理部分,插入,輔助視圖,變量單元格等,它很快會變成一個錯誤的,低效率的糾結。

請告訴我我錯過了簡單的東西已經在sdk。

回答

1

我認爲使用UICollectionView indexPathForItemAtPoint:方法會更好。

根據targetContentOffset和收集視圖的contentSize計算收集視圖可見區域的左上角和右下角點。

然後用這兩點得到兩個對應的indexPath值。這會給你你的firstVisiblelastVisible索引路徑。

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset { 
    UICollectionView *collectionView = (UICollectionView *)scrollView; 
    CGPoint topLeft = CGPointMake(targetContentOffset->x + 1, targetContentOffset->y + 1); 
    CGPoint bottomRight = CGPointMake(topLeft.x + scrollView.bounds.size.width - 2, topLeft.y + scrollView.bounds.size.height - 2); 

    NSIndexPath *firstVisible = [collectionView indexPathForItemAtPoint:topLeft]; 
    firstVisible = (firstVisible)? firstVisible : [NSIndexPath indexPathForItem:0 inSection:0]; 
    NSIndexPath *lastVisible = [collectionView indexPathForItemAtPoint:bottomRight]; 
    lastVisible = (lastVisible)? lastVisible : [NSIndexPath indexPathForItem:self.model.count-1 inSection:0]; 

    NSMutableArray *willBeVisibleIndexPaths = [@[] mutableCopy]; 
    for (NSInteger i=firstVisible.row; i<lastVisible.row; i++) { 
     [willBeVisibleIndexPaths addObject:[NSIndexPath indexPathForItem:i inSection:0]]; 
    } 
} 

這只是一個部分的解決方案。最有可能的情況是lastVisible將是nil。您需要檢查並將lastVisible設置爲集合的最後一個indexPath。由於這些點位於頁眉或頁腳視圖上,因此firstVisiblelastVisible也可能爲nil

+0

非常感謝。將按照注意事項處理更通用的版本(並且會修復帖子中的幾個編譯錯誤),然後在此處建議編輯。你能解釋topLeft點的+1遞增和bottomRight的-1遞減嗎? – danh

+0

隨時編輯我的答案,修復任何錯別字。我只是在沒有任何測試的情況下輸入。 + 1/-1只是「插入」一點點,以幫助確保這些點實際上在這些點的內部項目。 – rmaddy

+0

如果您不同意這個問題,請讓我知道。 – danh

相關問題