Skip to content

Commit

Permalink
Update Swift Package Manager's Source File
Browse files Browse the repository at this point in the history
  • Loading branch information
ShawnBaek committed Jan 27, 2020
1 parent dd55154 commit 0a5e701
Showing 1 changed file with 53 additions and 97 deletions.
150 changes: 53 additions & 97 deletions Sources/Slippery/Slippery.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,17 @@ import UIKit

public enum Base {
case leading

}

public enum ItemAt : Int {
case first = 1
case second = 2
case third = 3
case fourth = 4
case fifth = 5
case second
case third
case fourth
case fifth
}

//typealias ItemAt = Base.ItemAt

public enum Center {
case cropping
case normal
Expand All @@ -34,16 +32,14 @@ public enum HighlightItem {
}


@available(iOS 10.0, *)
@available(iOS 11.0, *)
public class SlipperyFlowLayout: UICollectionViewFlowLayout {
private var lastCollectionViewSize: CGSize = .zero

private var baseOffset: CGFloat = 200
public var minimumScaleFactor: CGFloat = 0.5
public var minimumOpacityFactor: CGFloat = 0.5

public var pageCount: Int = 0

private var pageWidth: CGFloat = 0 {
didSet {
baseOffset = pageWidth
Expand All @@ -54,33 +50,36 @@ public class SlipperyFlowLayout: UICollectionViewFlowLayout {
private var boundsCenter: CGFloat = 0
private var customOffset: CGFloat = 0

public var highlightOffsetForCell: HighlightItem = HighlightItem.center(.normal)
private var highlightOffsetForCell: HighlightItem = .center(.normal)
public var initialOffset: CGFloat = 0


public static func configureLayout(collectionView: UICollectionView, itemSize: CGSize, minimumLineSpacing: CGFloat, highlightOption: HighlightItem) -> SlipperyFlowLayout {

public static func configureLayout(
collectionView: UICollectionView,
itemSize: CGSize,
minimumLineSpacing: CGFloat,
highlightOption: HighlightItem = .center(.normal)
) -> SlipperyFlowLayout {
let layout = SlipperyFlowLayout()
assert(
itemSize.height.isLessThanOrEqualTo(collectionView.bounds.height),
"Item height should be less then collectionView's height"
)
layout.scrollDirection = .horizontal
layout.minimumLineSpacing = minimumLineSpacing
layout.itemSize = itemSize
layout.highlightOffsetForCell = highlightOption
collectionView.decelerationRate = UIScrollViewDecelerationRateFast
collectionView.decelerationRate = UIScrollView.DecelerationRate.fast
collectionView.collectionViewLayout = layout

return layout
}

public func updateOffset(item: Int) -> CGFloat {

if self.collectionView == nil {
guard let collectionView = self.collectionView else {
return initialOffset
}

var updateOffset = CGFloat()

let inset = self.collectionView!.bounds.size.width / 2 - self.itemSize.width / 2
let cropInset = -(self.itemSize.width - (inset - self.minimumLineSpacing))
let inset = collectionView.bounds.size.width / 2 - itemSize.width / 2
let cropInset = -(itemSize.width - (inset - minimumLineSpacing))

switch highlightOffsetForCell {
case .center(let mode):
Expand All @@ -90,83 +89,71 @@ public class SlipperyFlowLayout: UICollectionViewFlowLayout {
updateOffset = -inset + initialOffset + CGFloat(item) * pageWidth
}
case .custom(let base, let itemAt):


if base == .leading {

guard item - itemAt.rawValue > 0 else { return initialOffset }
updateOffset = initialOffset + (pageWidth * CGFloat(item - itemAt.rawValue - 1)) - itemCenter
}

}

return updateOffset

}

private func configureInset(for option: HighlightItem) {
if self.collectionView == nil {
guard let collectionView = self.collectionView else {
return
}

let inset = self.collectionView!.bounds.size.width / 2 - self.itemSize.width / 2
let cropInset = -(self.itemSize.width - (inset - self.minimumLineSpacing))
let inset = collectionView.bounds.size.width / 2 - itemSize.width / 2
let cropInset = -(itemSize.width - (inset - minimumLineSpacing))

pageWidth = itemSize.width + minimumLineSpacing
itemCenter = itemSize.width / 2
boundsCenter = self.collectionView!.bounds.size.width / 2

switch option {
case .center(let mode):
if mode == .cropping {
self.collectionView!.contentInset = UIEdgeInsetsMake(0, cropInset, 0 , cropInset)
self.collectionView!.contentOffset = CGPoint(x: -cropInset, y: 0)
collectionView.contentInset = UIEdgeInsets.init(top: 0, left: cropInset, bottom: 0 , right: cropInset)
collectionView.contentOffset = CGPoint(x: -cropInset, y: 0)
initialOffset = pageWidth
}else {
self.collectionView!.contentInset = UIEdgeInsetsMake(0, inset, 0 , inset)
self.collectionView!.contentOffset = CGPoint(x: -inset, y: 0)
} else {
collectionView.contentInset = UIEdgeInsets.init(top: 0, left: inset, bottom: 0 , right: inset)
collectionView.contentOffset = CGPoint(x: -inset, y: 0)
initialOffset = 0

}
case .custom(let base, let itemAt):

self.collectionView!.contentInset = UIEdgeInsetsMake(0, 0, 0, 0)

collectionView.contentInset = UIEdgeInsets.init(top: 0, left: 0, bottom: 0, right: 0)
if base == .leading {
customOffset = (pageWidth * CGFloat(itemAt.rawValue - 1)) + itemCenter
initialOffset = CGFloat(itemAt.rawValue - 1) * (itemSize.width + minimumLineSpacing) + (itemSize.width / 2)

self.collectionView?.contentOffset = CGPoint(x: customOffset, y: 0)
collectionView.contentOffset = CGPoint(x: customOffset, y: 0)
}

}
}

public override func invalidateLayout(with context: UICollectionViewLayoutInvalidationContext) {
super.invalidateLayout(with: context)

if self.collectionView == nil {
guard let collectionView = self.collectionView else {
return
}

let currentCollectionViewSize = self.collectionView!.bounds.size
if !currentCollectionViewSize.equalTo(self.lastCollectionViewSize) {
let currentCollectionViewSize = collectionView.bounds.size
if !currentCollectionViewSize.equalTo(lastCollectionViewSize) {
self.configureInset(for: highlightOffsetForCell)
self.lastCollectionViewSize = currentCollectionViewSize
}
}

public override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {

if self.collectionView == nil {
guard let collectionView = self.collectionView else {
return proposedContentOffset
}

let collectionViewSize = self.collectionView!.bounds.size
let proposedRect = CGRect(x: proposedContentOffset.x, y: 0, width: collectionViewSize.width, height: collectionViewSize.height)
let collectionViewSize = collectionView.bounds.size
let proposedRect = CGRect(
x: proposedContentOffset.x,
y: 0,
width: collectionViewSize.width,
height: collectionViewSize.height
)

let layoutAttributes = self.layoutAttributesForElements(in: proposedRect)

if layoutAttributes == nil {
return proposedContentOffset
}
Expand All @@ -185,23 +172,20 @@ public class SlipperyFlowLayout: UICollectionViewFlowLayout {
if attributes.representedElementCategory != .cell {
continue
}

if candidateAttributes == nil {
candidateAttributes = attributes
continue
}

switch highlightOffsetForCell {
case .custom(_, _):
let attributesOffset = attributes.frame.origin.x + pageWidth
let candidateOffset = (candidateAttributes?.frame.origin.x)! + pageWidth
let proposedOffset = proposedContentOffsetCenterX + pageWidth

if fabs(attributesOffset - proposedOffset) < fabs(candidateOffset - proposedOffset) {
if abs(attributesOffset - proposedOffset) < abs(candidateOffset - proposedOffset) {
candidateAttributes = attributes
}
case .center(_):
if fabs(attributes.center.x - proposedContentOffsetCenterX) < fabs(candidateAttributes!.center.x - proposedContentOffsetCenterX) {
if abs(attributes.center.x - proposedContentOffsetCenterX) < abs(candidateAttributes!.center.x - proposedContentOffsetCenterX) {
candidateAttributes = attributes
}
}
Expand All @@ -213,89 +197,61 @@ public class SlipperyFlowLayout: UICollectionViewFlowLayout {

var newOffsetX = CGFloat()
switch highlightOffsetForCell {
case .custom(_, _):
case .custom:
newOffsetX = (candidateAttributes?.frame.origin.x)! - pageWidth
case .center(_):
case .center:
newOffsetX = candidateAttributes!.center.x - boundsCenter
}

let offset = newOffsetX - self.collectionView!.contentOffset.x

if(velocity.x < 0 && offset > 0 ) || (velocity.x > 0 && offset < 0) {
let pageWidth = self.itemSize.width + self.minimumLineSpacing
newOffsetX += velocity.x > 0 ? pageWidth: -pageWidth
}


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

public override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
return true
}


public override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {

// if !self.scaleItems || self.collectionView == nil {
// return super.layoutAttributesForElements(in: rect)
// }
if self.collectionView == nil {
guard let collectionView = self.collectionView else {
return super.layoutAttributesForElements(in: rect)
}

let superAttributes = super.layoutAttributesForElements(in: rect)

if superAttributes == nil {
guard let superAttributes = super.layoutAttributesForElements(in: rect) else {
return nil
}

let contentOffset = self.collectionView!.contentOffset
let size = self.collectionView!.bounds.size

let contentOffset = collectionView.contentOffset
let size = collectionView.bounds.size

let visibleRect = CGRect(x:contentOffset.x, y: contentOffset.y, width: size.width, height: size.height)

var visibleCenterX = CGFloat()

switch highlightOffsetForCell {
case .custom(_, _):
visibleCenterX = visibleRect.minX

case .center(_):
visibleCenterX = visibleRect.midX
}

var newAttributesArray = Array<UICollectionViewLayoutAttributes>()

for (_, attributes) in superAttributes!.enumerated(){

let newAttributes = attributes.copy() as! UICollectionViewLayoutAttributes
for attribute in superAttributes {
let newAttributes = attribute.copy() as! UICollectionViewLayoutAttributes
newAttributesArray.append(newAttributes)
var distanceFromCenter = CGFloat()

switch highlightOffsetForCell {

case .custom(_, _):
distanceFromCenter = visibleCenterX - newAttributes.center.x + customOffset

case .center(_):
distanceFromCenter = visibleCenterX - newAttributes.center.x

}

let absDistanceFromCenter = min(abs(distanceFromCenter), self.baseOffset)
let scale = absDistanceFromCenter * (self.minimumScaleFactor - 1) / self.baseOffset + 1
let opacity = absDistanceFromCenter * (self.minimumOpacityFactor - 1) / self.baseOffset + 1


newAttributes.transform3D = CATransform3DScale(CATransform3DIdentity, scale, scale, 1)
newAttributes.alpha = opacity

}

return newAttributesArray


}
}
}
}

0 comments on commit 0a5e701

Please sign in to comment.