2015-10-26 103 views
2

我有一個自定義UICollectionViewLayout,它實現targetContentOffsetForProposedContentOffset爲了設置分頁。 UICollectionView中的中心項目是完整的「大」尺寸,而每個其他項目具有「縮小」比例值的CGAffineTransformScaletargetContentOffsetForProposedContentOffset - 錯誤的建議偏移量

我的問題是,似乎有一個contentOffset的上限,以便我只能滾動到第5項的7,並且它反彈回來。

我設置collectionViewContentSize()如下:

@IBInspectable var shrunkScale: CGFloat = 0.5 // 0.5 in IB 
@IBInspectable var largeSize: CGSize = CGSizeZero // 360x490 in IB 
@IBInspectable var itemSpacing: CGFloat = 0 // 32 in IB 

var widthPerAdditionalItem: CGFloat { 
    return largeSize.width * shrunkScale + itemSpacing 
} 

override func collectionViewContentSize() -> CGSize { 
    guard let collectionView = self.collectionView else { 
     return CGSizeZero 
    } 

    let count = CGFloat(collectionView.numberOfItemsInSection(0)) 

    let width = largeSize.width + (count) * widthPerAdditionalItem 
    let height = collectionView.bounds.height 

    let size = CGSize(width: width, height: height) 

    return size 
} 

targetOffset...方法引用一個helper方法:代碼之後具體

override func targetContentOffsetForProposedContentOffset(proposedContentOffset: CGPoint) -> CGPoint { 

    let closestPlace = round(proposedContentOffset.x/widthPerAdditionalItem) 

    guard let offsetX = offsetXForItemAtIndex(Int(closestPlace)) else { 
     return proposedContentOffset 
    } 
    print("Calculated: \(offsetX), Proposed: \(proposedContentOffset.x), ContentWidth: \(collectionView?.contentSize.width ?? 0)") 
    return CGPoint(x: offsetX, y: proposedContentOffset.y) 
} 

override func targetContentOffsetForProposedContentOffset(proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint { 
    return targetContentOffsetForProposedContentOffset(proposedContentOffset) 
} 

func contentOffsetForItemAtIndexPath(indexPath: NSIndexPath) -> CGPoint? { 
    guard 
     let collectionView = self.collectionView, 
     let offsetX = offsetXForItemAtIndex(indexPath.item) 
    else { 
     return nil 
    } 
    print("Tap Offset: - \(offsetX) vs. \(collectionView.contentOffset.x)") 
    return CGPoint(x: offsetX, y: collectionView.contentOffset.y) 

} 

private func offsetXForItemAtIndex(index: Int) -> CGFloat? { 
    guard 
     let count = collectionView?.numberOfItemsInSection(0) 
    else { 
     return nil 
    } 

    let proposed = CGFloat(index) * widthPerAdditionalItem 
    let maximum = CGFloat(count) * widthPerAdditionalItem 

    // bound min = 0, max = count*width 
    return max(min(maximum, proposed), 0) 
} 

這是我能得到什麼:

  1. 我的內容寬度爲1844.0
  2. 我完成拖動在offset.x視圖= 1187.5
  3. targetContentOffsetForProposedContentOffset接收提出offset.x = 820.0
  4. 我返回848.0
  5. 的的CollectionView滾動 「尋呼」 offset.x值來抵消。的820.0

X什麼我期待:

  1. 我的小故事NT寬度是1844.0
  2. 我完成拖動在offset.x視圖= 1187.5
  3. targetContentOffsetForProposedContentOffset接收 提出offset.x = 1187.5
  4. 我返回1272.0
  5. 的 「尋呼」 offset.x值該的CollectionView滾動到offset.x 1272.0

調試的:

如果我手動調用setContentOffset並計算偏移量1272.0,那麼它會滾動到正確的位置。但我儘量把它的滾動的瞬間彈回820.0

回答

0

坐下來,做一些數學我想通了以下後:

contentWidth = 1844 
poposedContentOffset.x = 820 
1844 - 820 = 1024 // <--- Width of the screen. 

內容正在從中心的顯示第一個項目的屏幕,到第二個項目的屏幕的中心

這意味着我需要添加一半的collectionView的frame.width,所以第一個項目可以居中,再一半,所以最終的項目可以居中。

collectionViewContentSize()現在返回

let width = (count-1) * widthPerAdditionalItem + collectionView.bounds.width 
let height = collectionView.bounds.height 
let size = CGSize(width: width, height: height) 
相關問題