From 0a5e701fa07f4778b0113ba54d6ed9d44c538627 Mon Sep 17 00:00:00 2001 From: ShawnBaek Date: Mon, 27 Jan 2020 11:59:39 +0900 Subject: [PATCH] Update Swift Package Manager's Source File --- Sources/Slippery/Slippery.swift | 150 +++++++++++--------------------- 1 file changed, 53 insertions(+), 97 deletions(-) diff --git a/Sources/Slippery/Slippery.swift b/Sources/Slippery/Slippery.swift index e533557..d658aee 100644 --- a/Sources/Slippery/Slippery.swift +++ b/Sources/Slippery/Slippery.swift @@ -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 @@ -34,7 +32,7 @@ public enum HighlightItem { } -@available(iOS 10.0, *) +@available(iOS 11.0, *) public class SlipperyFlowLayout: UICollectionViewFlowLayout { private var lastCollectionViewSize: CGSize = .zero @@ -42,8 +40,6 @@ public class SlipperyFlowLayout: UICollectionViewFlowLayout { 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 @@ -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): @@ -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 } @@ -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 } } @@ -213,20 +197,17 @@ 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) } @@ -234,68 +215,43 @@ public class SlipperyFlowLayout: UICollectionViewFlowLayout { 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() - - 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 - - - } -} \ No newline at end of file + } +}