我的UICollectionView中有40个单元格,如果我想滚动到特定单元格(通过单击按钮),我会遇到问题。
它永远不会进入理想的细胞。
它总是关闭一两个单元格。
这是项目的链接: https://www.dropbox.com/sh/jey73k0tjubx9ld/AAA-RSpqmP18DiOuGRNDNHvaa?dl=0
class VerticalLayout: UICollectionViewFlowLayout {
private var cache = [UICollectionViewLayoutAttributes]()
var contentWidth: CGFloat = 0
override func collectionViewContentSize() -> CGSize {
return CGSize(width: contentWidth , height: CGFloat(statics.height))
}
override func targetContentOffsetForProposedContentOffset(proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {
let midWidth = collectionView!.bounds.size.width * 0.5
let centerX = proposedContentOffset.x + midWidth
let proposedRect = self.collectionView!.bounds
var candidateAttributes: UICollectionViewLayoutAttributes?
for attributes in layoutAttributesForElementsInRect(proposedRect)! {
// set candidate if none
if candidateAttributes == nil {
candidateAttributes = attributes as? UICollectionViewLayoutAttributes
// else set if better match
} else if let
candidate = candidateAttributes,
attributes = attributes as? UICollectionViewLayoutAttributes
where fabs(attributes.center.x - centerX) < fabs(candidate.center.x - centerX) {
candidateAttributes = attributes
}
}
if let candidateAttributes = candidateAttributes {
let lowerBound: CGFloat = 0
let upperBound: CGFloat = cache.last!.frame.origin.x - cache.first!.frame.origin.x - 1
return CGPoint(
x: min(upperBound, max(lowerBound, candidateAttributes.center.x - midWidth)),
y: proposedContentOffset.y
)
} else {
return proposedContentOffset
}
}
override func prepareLayout() {
super.prepareLayout()
self.scrollDirection = .Horizontal
let start = Int(collectionView!.bounds.size.width * 0.6 ) - statics.width / 2
let length = collectionView!.numberOfItemsInSection(0)
if cache.isEmpty && length > 0 {
for item in 0..<length {
let indexPath = NSIndexPath(forItem: item, inSection: 0)
let attributes = UICollectionViewLayoutAttributes(forCellWithIndexPath: indexPath)
attributes.frame = CGRect(
x: start + (statics.width + statics.padding ) * indexPath.item ,
y: 0,
width: statics.width ,
height: statics.height
)
cache.append(attributes)
}
contentWidth = CGRectGetMaxX(cache.last!.frame) + CGFloat(start)
}
}
// 3
override func layoutAttributesForElementsInRect(rect: CGRect) -> [AnyObject]? {
var layoutAttributes = [UICollectionViewLayoutAttributes]()
for attributes in cache {
if CGRectIntersectsRect(attributes.frame, rect) {
layoutAttributes.append(attributes)
}
}
println(layoutAttributes)
return layoutAttributes
}
override func shouldInvalidateLayoutForBoundsChange(newBounds: CGRect) -> Bool {
return true
}