2014-01-22 194 views
1

您將如何執行此行爲的UICollectionView? 這個想法是,一旦用戶導航過去某個點,他們不能回去再次查看這些單元格。UICollectionView只能向右滾動(無左,向上或向下)

我對解決方案的嘗試一直是在集合視圖上監聽手勢,並且如果在元素上發生輕掃時禁用滾動。與此明顯的問題是,用戶可以簡單地保持並拖動任何特定的單元格。

有什麼想法?

+0

可能的方法:從數據源中刪除項目在屏幕的左側,並調用reloadData每次。所以左邊的單元格總是第一個單元格。 – rounak

回答

1

我認爲這種行爲可能會讓您的用戶感到困惑。

也許你應該嘗試添加一些彈性/彈跳,以便你的用戶不會感到困惑。

無論如何,我看到了兩個不同的方式來實現這一目標沒有子

1 /由於UICollectionViewDelegate符合UIScrollViewDelegate,你可以得到的開始– scrollViewWillBeginDragging:抵消你的滾動型的,然後在– scrollViewDidScroll:你會比較新的偏移量的x值。如果新的offset.x的值小於初始值,則將其設置爲0並更新滾動視圖。

#pragma mark - UIScrollViewDelegate 

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { 
    offset = scrollView.contentOffset; 
} 

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {   

    CGPoint newOffset = scrollView.contentOffset; 

    if (newOffset.x < offset.x) { 
     // scrolling to the left, reset offset 
     [scrollView setContentOffset:offset]; 
    } 
} 

因爲有慣性與iOS中滾動,scrollViewDidScroll:叫了大量的時間,因此可能會導致性能問題。您可以通過從UIScrollViewDelegate以scrollViewWillEndDragging:withVelocity:targetContentOffset:爲目標來減少通話次數。 2 /或ou可以使用我剛纔談到的方法scrollViewWillEndDragging:withVelocity:targetContentOffset:,它使用動畫將偏移量設置回到開頭。

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset { 

    CGPoint newOffset = scrollView.contentOffset; 

    if (newOffset.x < offset.x) { 
     // scrolling to the left, reset offset with animation 
     targetContentOffset->x = offset.x; 
    } 
} 

3 /你剛纔談到的UISwipeGestureRecognizer,你給一個嘗試UIPanGestureRecognizer?這就是「簡單的保持和拖動」。

0

您可以按照實現無限滾動視圖的相同方式實現它,方法是根據滾動偏移量添加/刪除項目。

  1. 重寫viewDidScroll:方法(UICollectionViewDelegate
  2. 檢查您的偏移將第一個對象列表的過去的偏移量(即你還能看到它在屏幕上?)
  3. 如果是,然後從集合視圖中刪除它。

這個簡單的實現可能會導致動盪不定,你可能必須做一些優化,一旦它的工作,但這應該讓你開始。

0

另一個可能的解決方案是在你開始滾動之前,如果你正在向左滾動,「重新定位」你的所有元素不斷出現在他們所在的位置。

您可以通過跟蹤您遇到的最高偏移量X來實現此目的,並在當前偏移量X低於最大偏移量X時重新定位單元格。這樣你就會有這樣的印象:你的單元不移動,或者你不能滾動,但你實際上會滾動。

0

在我的情況下,我有一個分頁的集合視圖,所以在收集視圖的最後一個項目中減速時以及在每個頁面的自動減速時都必須小心。

要解決此問題,我只是在收集視圖「自動移動」時禁用用戶交互。

下面的代碼:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView 
{ 
    if (!_isDragging) // <-- only do things if the user is dragging! 
     return; 

    CGPoint contentOffset = scrollView.contentOffset; 

    // If we move to the left 
    if (contentOffset.x < _contentOffset.x) 
    { 
     CGSize contentSize = scrollView.contentSize; 

     // If content offset is moving inside contentSize: 
     if ((contentOffset.x + scrollView.bounds.size.width) < contentSize.width) 
      scrollView.contentOffset= _contentOffset; 
    } 
    else  
    { 
     // Update the current content offset 
     _contentOffset = contentOffset; 
    } 
} 

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView 
{ 
    _isDragging = YES;  
} 

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset 
{ 
    _isDragging = NO; 
} 

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate 
{ 
    if (decelerate) 
    { 
     // If willDecelerate, stop user interaction! 
     _collectionView.userInteractionEnabled = NO; 
    } 
} 

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView 
{ 
    // Once deceleration is finished, enbale user interaction 
    _collectionView.userInteractionEnabled = YES; 

    // Set the new content offset 
    _contentOffset = scrollView.contentOffset; 
} 
+0

這裏有一些好主意,但是_isDragging邏輯是不必要的,因爲'scrollViewDidScroll'只在用戶滾動時被調用 – user2387855

+0

想象一下你處於最後一個單元格的情況,並且你甚至進一步拖動集合視圖。一旦你停止拖動收藏視圖將自動生成動畫以適應內容大小。但是,此動畫是在「禁止」方向完成的,除非您明確拖動集合視圖時進行跟蹤,否則內容偏移量的動畫將通過「-scrollViewDidScroll」停止。 在我的代碼中,我正在跟蹤用戶拖動的時間,如果沒有,我讓集合視圖自由移動,允許這些動畫。 – vilanovi

+0

哦,我明白你的意思了。通常我會同意你這種行爲是可取的,但在我的實現中,我實際上只是使用'UICollectionView'作爲一種低效的方式來實現具有用戶定義的物理,外觀等的拖曳輪。它不顯示任何有意義的數據給用戶。我的意圖是讓它像棘輪一樣行動;它的運動純粹是單向的。我的問題應該更清楚。 – user2387855

相關問題