2012-02-20 127 views
19

我想使用新的scrollViewWillEndDragging:withVelocity:targetContentOffset:iOS 5中的UIScrollView委託調用,但我似乎無法得到它實際上正確迴應我。我正在更改targetContentOffset-> x值,但它永遠不會被使用。我知道代碼正在運行,因爲它會在該函數中發生斷點。我甚至嘗試將偏移值設置爲硬編碼數字,所以我會知道它會在哪裏結束,但它永遠不會工作。自定義UIScrollView分頁與scrollViewWillEndDragging

有沒有人能夠正確使用它,並使其工作?是否還有其他必須實施的代表呼叫才能使其工作?

這裏是我萬一有人看到代碼什麼毛病吧:

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset 
{ 
    // goodOffsetX returns the contentOffset i want the scrollView to stop at 
    CGFloat goodOffsetX = [self _horizontalContentOffsetForTargetHorizontalContentOffset:(*targetContentOffset).x velocity:velocity.x]; 

    NSLog(@" "); 
    NSLog(@"scrollViewWillEndDragging"); 
    NSLog(@" velocity: %f", velocity.x); 
    NSLog(@" currentX: %f", scrollView.contentOffset.x); 
    NSLog(@" uikit targetX: %f", (*targetContentOffset).x); 
    NSLog(@" pagedX: %f", goodOffsetX); 

    targetContentOffset->x = goodOffsetX; 
} 
+2

演示你有'pagingEnabled'設置爲'YES'這個滾動視圖? – 2012-02-20 20:36:17

+3

pagingEnabled設置爲NO,文檔說它需要設置爲NO才能調用該代理。我也嘗試將它設置爲YES僅用於踢腿,並且不會按照文檔調用,但有一些控制檯日誌記錄表示不會將pagingEnabled設置爲YES。 – Alex 2012-02-20 20:47:41

+0

我的問題是我在運行iOS4的手機上測試它。 另外,你有沒有設置UIScrollView的委託屬性? – Marc 2012-04-04 12:40:59

回答

49

可以實現自定義分頁使用此代碼:

- (float) pageWidth { 
    return ((UICollectionViewFlowLayout*)self.collectionView.collectionViewLayout).itemSize.width + 
    ((UICollectionViewFlowLayout*)self.collectionView.collectionViewLayout).minimumInteritemSpacing; 
} 

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

    CGFloat pageWidth = self.collectionView.frame.size.width + 10 /* Optional Photo app like gap between images. Or use [self pageWidth] in case if you want the next page be also visible */; 

    _currentPage = floor((self.collectionView.contentOffset.x - pageWidth/2)/pageWidth) + 1; 

    NSLog(@"Dragging - You are now on page %i", _currentPage); 
} 

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

    CGFloat pageWidth = self.collectionView.frame.size.width + 10; // [self pageWidth] 

    int newPage = _currentPage; 

    if (velocity.x == 0) { // slow dragging not lifting finger 
     newPage = floor((targetContentOffset->x - pageWidth/2)/pageWidth) + 1; 
    } 
    else { 
     newPage = velocity.x > 0 ? _currentPage + 1 : _currentPage - 1; 

     if (newPage < 0) 
      newPage = 0; 
     if (newPage > self.collectionView.contentSize.width/pageWidth) 
      newPage = ceil(self.collectionView.contentSize.width/pageWidth) - 1.0; 
    } 

    NSLog(@"Dragging - You will be on %i page (from page %i)", newPage, _currentPage); 

    *targetContentOffset = CGPointMake(newPage * pageWidth, targetContentOffset->y); 
} 

當然,你必須設置pagingEnabled = NO。 _currentPage是一個類iVar。 感謝http://www.mysamplecode.com/2012/12/ios-scrollview-example-with-paging.html指向正確的方向。

+6

這是我迄今爲止發現的模擬默認實現的最佳解決方案(一次只滾動一個頁面,處理緩慢的拖動等) – 2013-08-26 20:20:56

+2

這可以工作,但如果拖動速度太小,拖動結束將向新頁面移動得太慢。有關如何解決這個問題的任何建議? – skagedal 2015-11-08 09:02:39

+13

要回答我自己的問題,請設置self.scrollView.decelerationRate = UIScrollViewDecelerationRateFast,事情會很好! :) – skagedal 2015-11-08 11:14:07

7

我能夠運行一個快速測試,並得到這個正確火,讓我的對象停止根據需要。我這樣做是使用以下簡單的測試:

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset 
{ 
    targetContentOffset->x = scrollView.contentOffset.x - 10;  
} 

看來,這種方法很可能不是在你的代碼的問題,但它更可能是你的「goodOffsetX」沒有正確計算有效值停止在。

3

雨燕2.2:

extension SomeCollectionViewController { 

    override func scrollViewWillBeginDragging(scrollView: UIScrollView) { 
     let pageWidth = Float(collectionView!.frame.size.width) 
     let xCurrentOffset = Float(collectionView!.contentOffset.x) 
     currentPage = floor((xCurrentOffset - pageWidth/2)/pageWidth) + 1 
    } 

    override func scrollViewWillEndDragging(scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) { 
     let pageWidth = Float(collectionView!.frame.size.width) 
     let targetXContentOffset = Float(targetContentOffset.memory.x) 
     let contentWidth = Float(collectionView!.contentSize.width) 

     var newPage = currentPage 
     if velocity.x == 0 { 
      newPage = floor((targetXContentOffset - pageWidth/2)/pageWidth) + 1 
     } else { 
      newPage = velocity.x > 0 ? currentPage + 1 : currentPage - 1 
      if newPage < 0 { 
       newPage = 0 
      } 
      if newPage > contentWidth/pageWidth { 
       newPage = ceil(contentWidth/pageWidth) - 1.0 
      } 
     } 
     targetContentOffset.memory.x = CGFloat(newPage * pageWidth) 
    } 
} 

我還使用了collectionView?.decelerationRate = UIScrollViewDecelerationRateFast通過@skagedal的建議,以提高速度。

6

SWIFT 3

隨着這裏https://github.com/damienromito/CollectionViewCustom

func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) { 

    let pageWidth = Float(itemWidth + itemSpacing) 
    let targetXContentOffset = Float(targetContentOffset.pointee.x) 
    let contentWidth = Float(collectionView!.contentSize.width ) 
    var newPage = Float(self.pageControl.currentPage) 

    if velocity.x == 0 { 
     newPage = floor((targetXContentOffset - Float(pageWidth)/2)/Float(pageWidth)) + 1.0 
    } else { 
     newPage = Float(velocity.x > 0 ? self.pageControl.currentPage + 1 : self.pageControl.currentPage - 1) 
     if newPage < 0 { 
      newPage = 0 
     } 
     if (newPage > contentWidth/pageWidth) { 
      newPage = ceil(contentWidth/pageWidth) - 1.0 
     } 
    } 
    let point = CGPoint (x: CGFloat(newPage * pageWidth), y: targetContentOffset.pointee.y) 
    targetContentOffset.pointee = point 
} 
+0

值得注意的是,如果您有頂部或左側插圖,則需要在分配之前將其添加到點值。 – Sethmr 2017-09-27 16:30:16

-1
public func scrollViewWillEndDragging(_ scrollView: UIScrollView ,withVelocity velocity: CGPoint, targetContentOffset: 
UnsafeMutablePointer<CGPoint>){ 

let pageWidth = Float(appWidth + itemSpacing) 
    let targetXContentOffset = Float(targetContentOffset.pointee.x) 
    var newPage = Float(currentPageIndex) 

    // I use this way calculate newPage: 
    newPage = roundf(targetXContentOffset/pageWidth); 

    //if velocity.x == 0 { 
    // newPage = floor((targetXContentOffset - Float(pageWidth)/2)/Float(pageWidth)) + 1.0 
    //} else { 
    // newPage = Float(velocity.x > 0 ? newPage + 1 : newPage - 1) 
    // if newPage < 0 { 
    //  newPage = 0 
    // } 
    // if (newPage > contentWidth/pageWidth) { 
    //  newPage = ceil(contentWidth/pageWidth) - 1.0 
    // } 
    //} 

    let targetOffsetX = CGFloat(newPage * pageWidth) 
    let point = CGPoint (x: targetOffsetX, y: targetContentOffset.pointee.y) 
    targetContentOffset.pointee = point 
}