5

Sto cercando di implementare lo "snap per effetto" ma non riuscivo a farlo funzionare, c'è qualcosa che sto facendo male?swift positionate center UICollectionViewCell

Subclassing UICollectionViewFlowLayout e prioritario targetContentOffsetForProposedContentOffset la funzione:

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

    var offsetAdjustment:CGFloat = CGFloat(MAXFLOAT) 
    let verticalCenter:CGFloat = proposedContentOffset.y + (CGRectGetHeight(self.collectionView!.bounds)/2.0) 
    let proposedRect:CGRect = CGRectMake(proposedContentOffset.x,0.0,self.collectionView!.bounds.size.width,self.collectionView!.bounds.size.height) 

    let array:NSArray = self.layoutAttributesForElementsInRect(proposedRect)! 

    for layoutAttributes : AnyObject in array { 

     if let _layoutAttributes = layoutAttributes as? UICollectionViewLayoutAttributes { 

      if _layoutAttributes.representedElementCategory != UICollectionElementCategory.Cell { 
       continue 
      } 

      let itemVerticalCenter:CGFloat = layoutAttributes.center.y 

      let _verticalCenter = fabsf(Float(itemVerticalCenter) - Float(verticalCenter)) 
      let _offsetAdjustment = fabsf(Float(offsetAdjustment)) 

      if (_verticalCenter < _offsetAdjustment) { 
       offsetAdjustment = itemVerticalCenter - verticalCenter 
      } 
     } 
    } 
    return CGPointMake(proposedContentOffset.x + offsetAdjustment, proposedContentOffset.y) 
} 

Sample project here e snap effect, desired output

risposta

0

Sono riuscito a scoprire, alla fine

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

    let rectBounds:CGRect = self.collectionView!.bounds 
    let halfHeight:CGFloat = rectBounds.size.height * CGFloat(0.45) 
    let proposedContentOffsetCenterY:CGFloat = proposedContentOffset.y + halfHeight 

    let attributesArray:NSArray = self.layoutAttributesForElementsInRect(rectBounds)! 

    var candidateAttributes:UICollectionViewLayoutAttributes? 

    for layoutAttributes : AnyObject in attributesArray { 

     if let _layoutAttributes = layoutAttributes as? UICollectionViewLayoutAttributes { 

      if _layoutAttributes.representedElementCategory != UICollectionElementCategory.Cell { 
       continue 
      } 

      if candidateAttributes == nil { 
       candidateAttributes = _layoutAttributes 
       self.delegate?.cellCenteredAtIndexPathWithCollectionView(self.collectionView!, layout: self, indexPath: candidateAttributes!.indexPath) 
       continue 
      } 

      if fabsf(Float(_layoutAttributes.center.y) - Float(proposedContentOffsetCenterY)) < fabsf(Float(candidateAttributes!.center.y) - Float(proposedContentOffsetCenterY)) { 
       candidateAttributes = _layoutAttributes 
       self.delegate?.cellCenteredAtIndexPathWithCollectionView(self.collectionView!, layout: self, indexPath: candidateAttributes!.indexPath) 
      } 
     } 
    } 

    if attributesArray.count == 0 { 
     return CGPointMake(proposedContentOffset.x,proposedContentOffset.y - halfHeight * 2) 
    } 

    return CGPointMake(proposedContentOffset.x,candidateAttributes!.center.y - halfHeight) 
} 

Inoltre non dimenticate di impostare il delegato:

class MyCostomFlow: UICollectionViewFlowLayout, UICollectionViewDelegateFlowLayout { 

    var delegate:MyFlowLayoutDelegate? 
} 

e il delegato stesso:

protocol MyFlowLayoutDelegate 
{ 
    func cellCenteredAtIndexPathWithCollectionView(collectionView: UICollectionView, layout: UICollectionViewLayout, indexPath: NSIndexPath) -> Void 
}