Skip to content

Commit

Permalink
Merge pull request #14 from VladIacobIonut/ShazamEffect
Browse files Browse the repository at this point in the history
Shazam card stack effect implementation
  • Loading branch information
JoniVR committed Oct 20, 2018
2 parents 073b010 + c2a6c45 commit edeb77d
Showing 1 changed file with 22 additions and 9 deletions.
31 changes: 22 additions & 9 deletions Sources/VerticalCardSwiperFlowLayout.swift
Expand Up @@ -40,13 +40,14 @@ internal class VerticalCardSwiperFlowLayout: UICollectionViewFlowLayout {
}

internal override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
let items = NSArray (array: super.layoutAttributesForElements(in: rect)!, copyItems: true)
let items = NSMutableArray (array: super.layoutAttributesForElements(in: rect)!, copyItems: true)

items.enumerateObjects(using: { (object, index, stop) -> Void in
let attributes = object as! UICollectionViewLayoutAttributes

self.updateCellAttributes(attributes)
})

return items as? [UICollectionViewLayoutAttributes]
}

Expand All @@ -66,32 +67,32 @@ internal class VerticalCardSwiperFlowLayout: UICollectionViewFlowLayout {

// Page height used for estimating and calculating paging.
let pageHeight = cellHeight + self.minimumLineSpacing

// Make an estimation of the current page position.
let approximatePage = self.collectionView!.contentOffset.y/pageHeight

// Determine the current page based on velocity.
let currentPage = (velocity.y < 0.0) ? floor(approximatePage) : ceil(approximatePage)

// Create custom flickVelocity.
let flickVelocity = velocity.y * 0.3
let flickVelocity = velocity.y * 0.4

// Check how many pages the user flicked, if <= 1 then flickedPages should return 0.
let flickedPages = (abs(round(flickVelocity)) <= 1) ? 0 : round(flickVelocity)

// Calculate newVerticalOffset.
let newVerticalOffset = ((currentPage + flickedPages) * pageHeight) - self.collectionView!.contentInset.top

return CGPoint(x: proposedContentOffset.x, y: newVerticalOffset)
}

internal override func finalLayoutAttributesForDisappearingItem(at itemIndexPath: IndexPath) -> UICollectionViewLayoutAttributes? {

// make sure the zIndex of the next card is higher than the one we're swiping away.
let nextIndexPath = IndexPath(row: itemIndexPath.row + 1, section: itemIndexPath.section)
let nextAttr = self.layoutAttributesForItem(at: nextIndexPath)
nextAttr?.zIndex = nextIndexPath.row

// attributes for swiping card away
let attr = self.layoutAttributesForItem(at: itemIndexPath)

Expand All @@ -104,18 +105,30 @@ internal class VerticalCardSwiperFlowLayout: UICollectionViewFlowLayout {
- parameter attributes: The attributes we're updating.
*/
fileprivate func updateCellAttributes(_ attributes: UICollectionViewLayoutAttributes) {
let minY = collectionView!.bounds.minY + collectionView!.contentInset.top

var minY = collectionView!.bounds.minY + collectionView!.contentInset.top
let maxY = attributes.frame.origin.y

if minY > attributes.frame.origin.y + attributes.bounds.height + minimumLineSpacing + collectionView!.contentInset.top {
minY = 0
}

let finalY = max(minY, maxY)
var origin = attributes.frame.origin
let deltaY = (finalY - origin.y) / attributes.frame.height
let translationScale = CGFloat((attributes.zIndex + 1) * 10)

// Card stack effect
if let itemTransform = firstItemTransform {
let scale = 1 - deltaY * itemTransform
attributes.transform = CGAffineTransform(scaleX: scale, y: scale)
// TODO: add card stack effect (like Shazam)
var t = CGAffineTransform.identity
t = t.scaledBy(x: scale, y: 1)
t = t.translatedBy(x: 0, y: (deltaY * translationScale))

attributes.transform = t
}

origin.x = (self.collectionView?.frame.width)! / 2 - attributes.frame.width / 2 - (self.collectionView?.contentInset.left)!
origin.y = finalY
attributes.frame = CGRect(origin: origin, size: attributes.frame.size)
attributes.zIndex = attributes.indexPath.row
Expand Down

0 comments on commit edeb77d

Please sign in to comment.