Support vertical paging.

This commit is contained in:
WenchaoD 2017-03-13 12:10:16 +08:00
parent 8c649841ee
commit de1bfbb109
11 changed files with 216 additions and 69 deletions

View File

@ -1,7 +1,7 @@
Pod::Spec.new do |s|
s.name = "FSPagerView"
s.version = "0.3.0"
s.version = "0.4.0"
s.summary = "FSPagerView is an elegant Screen Slide Library for making Banner、Product Show、Welcome/Guide Pages、Screen/ViewController Sliders."
s.homepage = "https://github.com/WenchaoD/FSPagerView"

View File

@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>0.3.0</string>
<string>0.4.0</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSPrincipalClass</key>

View File

@ -7,7 +7,7 @@
<key>FSPagerViewExample-Objc.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
<integer>1</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>

View File

@ -7,4 +7,7 @@
<FileRef
location = "group:FSPagerViewExample-Objc/FSPagerViewExample-Objc.xcodeproj">
</FileRef>
<FileRef
location = "group:FSPagerView/FSPagerView.xcodeproj">
</FileRef>
</Workspace>

View File

@ -14,6 +14,7 @@
## Features
* ***Infinite*** scrolling.
* ***Automatic*** Sliding.
* Support ***Horizontal*** and ***Vertical*** paging.
* Fully customizable item, with predefined banner-style item.
* Fully customizable ***page control***.
* Rich build-in 3D transformers.
@ -398,4 +399,6 @@ FSPageControl *pageControl = [[FSPageControl alloc] initWithFrame:frame2];
* <img src="https://cloud.githubusercontent.com/assets/5186464/22828152/b83ab04e-efd6-11e6-9baf-37abf0ae29c0.png" style="margin-bottom:-8px"/>
***[FSCalendar](https://github.com/WenchaoD/FSCalendar)***
---
# [Documentation](http://cocoadocs.org/docsets/FSPagerView)

View File

@ -14,6 +14,7 @@
## Features
* ***Infinite*** scrolling.
* ***Automatic*** Sliding.
* ***Horizontal*** and ***Vertical*** paging.
* Fully customizable item, with predefined banner-style item.
* Fully customizable ***page control***.
* Rich build-in 3D transformers.
@ -405,5 +406,6 @@ func pagerViewDidEndDecelerating(_ pagerView: FSPagerView)
* <img src="https://cloud.githubusercontent.com/assets/5186464/22828152/b83ab04e-efd6-11e6-9baf-37abf0ae29c0.png" style="margin-bottom:-8px"/>
***[FSCalendar](https://github.com/WenchaoD/FSCalendar)***
---
# [Documentation](http://cocoadocs.org/docsets/FSPagerView)

View File

@ -14,6 +14,7 @@ class FSPagerViewLayout: UICollectionViewLayout {
internal var leadingSpacing: CGFloat = 0
internal var itemSpacing: CGFloat = 0
internal var needsReprepare = true
internal var scrollDirection: FSPagerViewScrollDirection = .horizontal
open override class var layoutAttributesClass: AnyClass {
get {
@ -82,17 +83,27 @@ class FSPagerViewLayout: UICollectionViewLayout {
}
return pagerView.interitemSpacing
}()
self.leadingSpacing = (collectionView.frame.width-self.actualItemSize.width)*0.5
self.itemSpacing = self.actualItemSize.width+self.actualInteritemSpacing
self.scrollDirection = pagerView.scrollDirection
self.leadingSpacing = self.scrollDirection == .horizontal ? (collectionView.frame.width-self.actualItemSize.width)*0.5 : (collectionView.frame.height-self.actualItemSize.height)*0.5
self.itemSpacing = (self.scrollDirection == .horizontal ? self.actualItemSize.width : self.actualItemSize.height) + self.actualInteritemSpacing
// Calculate and cache contentSize, rather than calculating each time
self.contentSize = {
let numberOfItems = self.numberOfItems*self.numberOfSections
var contentSizeWidth: CGFloat = self.leadingSpacing*2 // Leading & trailing spacing
contentSizeWidth += CGFloat(numberOfItems-1)*self.actualInteritemSpacing // Interitem spacing
contentSizeWidth += CGFloat(numberOfItems)*self.actualItemSize.width // Item sizes
let contentSize = CGSize(width: contentSizeWidth, height: collectionView.frame.height)
return contentSize
switch self.scrollDirection {
case .horizontal:
var contentSizeWidth: CGFloat = self.leadingSpacing*2 // Leading & trailing spacing
contentSizeWidth += CGFloat(numberOfItems-1)*self.actualInteritemSpacing // Interitem spacing
contentSizeWidth += CGFloat(numberOfItems)*self.actualItemSize.width // Item sizes
let contentSize = CGSize(width: contentSizeWidth, height: collectionView.frame.height)
return contentSize
case .vertical:
var contentSizeHeight: CGFloat = self.leadingSpacing*2 // Leading & trailing spacing
contentSizeHeight += CGFloat(numberOfItems-1)*self.actualInteritemSpacing // Interitem spacing
contentSizeHeight += CGFloat(numberOfItems)*self.actualItemSize.height // Item sizes
let contentSize = CGSize(width: collectionView.frame.width, height: contentSizeHeight)
return contentSize
}
}()
self.adjustCollectionViewBounds()
}
@ -115,36 +126,36 @@ class FSPagerViewLayout: UICollectionViewLayout {
return layoutAttributes
}
// Calculate start position and index of certain rects
let numberOfItemsBefore = max(Int((rect.minX-self.leadingSpacing)/self.itemSpacing),0)
let numberOfItemsBefore = self.scrollDirection == .horizontal ? max(Int((rect.minX-self.leadingSpacing)/self.itemSpacing),0) : max(Int((rect.minY-self.leadingSpacing)/self.itemSpacing),0)
let startPosition = self.leadingSpacing + CGFloat(numberOfItemsBefore)*self.itemSpacing
let startIndex = numberOfItemsBefore
// Create layout attributes
var itemIndex = startIndex
var x = startPosition
let maxPosition = min(rect.maxX,self.contentSize.width-self.actualItemSize.width-self.leadingSpacing)
while x <= maxPosition {
var origin = startPosition
let maxPosition = self.scrollDirection == .horizontal ? min(rect.maxX,self.contentSize.width-self.actualItemSize.width-self.leadingSpacing) : min(rect.maxY,self.contentSize.height-self.actualItemSize.height-self.leadingSpacing)
while origin <= maxPosition {
let indexPath = IndexPath(item: itemIndex%self.numberOfItems, section: itemIndex/self.numberOfItems)
let attributes = self.layoutAttributesForItem(at: indexPath) as! FSPagerViewLayoutAttributes
self.applyTransform(to: attributes)
self.applyTransform(to: attributes, with: self.pagerView?.transformer)
layoutAttributes.append(attributes)
itemIndex += 1
x += self.itemSpacing
origin += self.itemSpacing
}
return layoutAttributes
}
override open func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
guard let collectionView = self.collectionView else {
return UICollectionViewLayoutAttributes(forCellWith: indexPath)
var attributes = self.layoutAttributes[indexPath]
if attributes == nil {
attributes = FSPagerViewLayoutAttributes(forCellWith: indexPath)
self.layoutAttributes[indexPath] = attributes
}
if let attributes = self.layoutAttributes[indexPath] {
return attributes
}
let attributes = FSPagerViewLayoutAttributes(forCellWith: indexPath)
let x = self.frame(for: indexPath).minX
let center = CGPoint(x: x+self.actualItemSize.width*0.5, y: collectionView.frame.height*0.5)
attributes.center = center
attributes.size = self.actualItemSize
let frame = self.frame(for: indexPath)
let center = CGPoint(x: frame.midX, y: frame.midY)
attributes!.center = center
attributes!.size = self.actualItemSize
self.layoutAttributes[indexPath] = attributes
return attributes
}
@ -155,6 +166,9 @@ class FSPagerViewLayout: UICollectionViewLayout {
}
var proposedContentOffset = proposedContentOffset
let proposedContentOffsetX: CGFloat = {
if self.scrollDirection == .vertical {
return proposedContentOffset.x
}
let translation = -collectionView.panGestureRecognizer.translation(in: collectionView).x
var offset: CGFloat = round(proposedContentOffset.x/self.itemSpacing)*self.itemSpacing
let minFlippingDistance = min(0.5 * self.itemSpacing,150)
@ -166,7 +180,22 @@ class FSPagerViewLayout: UICollectionViewLayout {
}
return offset
}()
proposedContentOffset = CGPoint(x: proposedContentOffsetX, y: proposedContentOffset.y)
let proposedContentOffsetY: CGFloat = {
if self.scrollDirection == .horizontal {
return proposedContentOffset.y
}
let translation = -collectionView.panGestureRecognizer.translation(in: collectionView).y
var offset: CGFloat = round(proposedContentOffset.y/self.itemSpacing)*self.itemSpacing
let minFlippingDistance = min(0.5 * self.itemSpacing,150)
let originalContentOffsetY = collectionView.contentOffset.y - translation
if abs(translation) <= minFlippingDistance {
if abs(velocity.y) >= 0.3 && abs(proposedContentOffset.y-originalContentOffsetY) <= self.itemSpacing*0.5 {
offset += self.itemSpacing * (velocity.y)/abs(velocity.y)
}
}
return offset
}()
proposedContentOffset = CGPoint(x: proposedContentOffsetX, y: proposedContentOffsetY)
return proposedContentOffset
}
@ -182,14 +211,38 @@ class FSPagerViewLayout: UICollectionViewLayout {
guard let collectionView = self.collectionView else {
return origin
}
let contentOffset = CGPoint(x: origin.x - (collectionView.frame.width*0.5-self.actualItemSize.width*0.5), y: collectionView.contentOffset.y)
let contentOffsetX: CGFloat = {
if self.scrollDirection == .vertical {
return 0
}
let contentOffsetX = origin.x - (collectionView.frame.width*0.5-self.actualItemSize.width*0.5)
return contentOffsetX
}()
let contentOffsetY: CGFloat = {
if self.scrollDirection == .horizontal {
return 0
}
let contentOffsetY = origin.y - (collectionView.frame.height*0.5-self.actualItemSize.height*0.5)
return contentOffsetY
}()
let contentOffset = CGPoint(x: contentOffsetX, y: contentOffsetY)
return contentOffset
}
internal func frame(for indexPath: IndexPath) -> CGRect {
let numberOfItems = self.numberOfItems*indexPath.section + indexPath.item
let originX = self.leadingSpacing + CGFloat(numberOfItems)*self.itemSpacing
let originY = (self.collectionView!.frame.height-self.actualItemSize.height)/2.0
let originX: CGFloat = {
if self.scrollDirection == .vertical {
return (self.collectionView!.frame.width-self.actualItemSize.width)*0.5
}
return self.leadingSpacing + CGFloat(numberOfItems)*self.itemSpacing
}()
let originY: CGFloat = {
if self.scrollDirection == .horizontal {
return (self.collectionView!.frame.height-self.actualItemSize.height)*0.5
}
return self.leadingSpacing + CGFloat(numberOfItems)*self.itemSpacing
}()
let origin = CGPoint(x: originX, y: originY)
let frame = CGRect(origin: origin, size: self.actualItemSize)
return frame
@ -217,23 +270,27 @@ class FSPagerViewLayout: UICollectionViewLayout {
}
let currentIndex = pagerView.currentIndex
let newIndexPath = IndexPath(item: currentIndex, section: self.isInfinite ? self.numberOfSections/2 : 0)
let contentOffsetX = self.contentOffset(for: newIndexPath).x
let contentOffset = CGPoint(x: contentOffsetX, y: 0)
let contentOffset = self.contentOffset(for: newIndexPath)
let newBounds = CGRect(origin: contentOffset, size: collectionView.frame.size)
collectionView.bounds = newBounds
}
fileprivate func applyTransform(to attributes: FSPagerViewLayoutAttributes) {
fileprivate func applyTransform(to attributes: FSPagerViewLayoutAttributes, with transformer: FSPagerViewTransformer?) {
guard let collectionView = self.collectionView else {
return
}
guard let transformer = self.pagerView?.transformer else {
guard let transformer = transformer else {
return
}
let ruler = collectionView.bounds.midX
attributes.center.x = self.frame(for: attributes.indexPath).midX
attributes.position = (attributes.center.x-ruler)/self.itemSpacing
attributes.interitemSpacing = self.actualInteritemSpacing
switch self.scrollDirection {
case .horizontal:
let ruler = collectionView.bounds.midX
attributes.position = (attributes.center.x-ruler)/self.itemSpacing
case .vertical:
let ruler = collectionView.bounds.midY
attributes.position = (attributes.center.y-ruler)/self.itemSpacing
}
attributes.zIndex = Int(self.numberOfItems)-Int(attributes.position)
transformer.applyTransform(to: attributes)
}

View File

@ -49,15 +49,25 @@ open class FSPagerViewTransformer: NSObject {
// Apply transform to attributes - zIndex: Int, frame: CGRect, alpha: CGFloat, transform: CGAffineTransform or transform3D: CATransform3D.
open func applyTransform(to attributes: FSPagerViewLayoutAttributes) {
guard let pagerView = self.pagerView else {
return
}
let position = attributes.position
let itemSpacing = attributes.interitemSpacing + attributes.bounds.width
let scrollDirection = pagerView.scrollDirection
let itemSpacing = (scrollDirection == .horizontal ? attributes.bounds.width : attributes.bounds.height) + self.proposedInteritemSpacing()
switch self.type {
case .none:
break
case .crossFading:
var zIndex = 0
var alpha: CGFloat = 0
let transform = CGAffineTransform(translationX: -itemSpacing * position, y: 0)
var transform = CGAffineTransform.identity
switch scrollDirection {
case .horizontal:
transform.tx = -itemSpacing * position
case .vertical:
transform.ty = -itemSpacing * position
}
if (abs(position) < 1) { // [-1,1]
// Use the default slide transition when moving to the left page
alpha = 1 - abs(position)
@ -80,11 +90,18 @@ open class FSPagerViewTransformer: NSObject {
case -1 ... 1 : // [-1,1]
// Modify the default slide transition to shrink the page as well
let scaleFactor = max(self.minimumScale, 1 - abs(position))
let vertMargin = attributes.bounds.height * (1 - scaleFactor) / 2;
let horzMargin = itemSpacing * (1 - scaleFactor) / 2;
transform.a = scaleFactor
transform.d = scaleFactor
transform.tx = position < 0 ? (horzMargin - vertMargin*2) : (-horzMargin + vertMargin*2)
switch scrollDirection {
case .horizontal:
let vertMargin = attributes.bounds.height * (1 - scaleFactor) / 2;
let horzMargin = itemSpacing * (1 - scaleFactor) / 2;
transform.tx = position < 0 ? (horzMargin - vertMargin*2) : (-horzMargin + vertMargin*2)
case .vertical:
let horzMargin = attributes.bounds.width * (1 - scaleFactor) / 2;
let vertMargin = itemSpacing * (1 - scaleFactor) / 2;
transform.ty = position < 0 ? (vertMargin - horzMargin*2) : (-vertMargin + horzMargin*2)
}
// Fade the page relative to its size.
alpha = self.minimumAlpha + (scaleFactor-self.minimumScale)/(1-self.minimumScale)*(1-self.minimumAlpha)
case 1 ... CGFloat.greatestFiniteMagnitude : // (1,+Infinity]
@ -111,18 +128,23 @@ open class FSPagerViewTransformer: NSObject {
transform.a = 1
transform.d = 1
zIndex = 1
case 0 ..< 1: // (0,1]
case 0 ..< 1: // (0,1)
// Fade the page out.
alpha = CGFloat(1.0) - position
// Counteract the default slide transition
transform.tx = itemSpacing * -position;
switch scrollDirection {
case .horizontal:
transform.tx = itemSpacing * -position
case .vertical:
transform.ty = itemSpacing * -position
}
// Scale the page down (between minimumScale and 1)
let scaleFactor = self.minimumScale
+ (1.0 - self.minimumScale) * (1.0 - abs(position));
transform.a = scaleFactor
transform.d = scaleFactor
zIndex = 0
case 1 ... CGFloat.greatestFiniteMagnitude: // (1,+Infinity]
case 1 ... CGFloat.greatestFiniteMagnitude: // [1,+Infinity)
// This page is way off-screen to the right.
alpha = 0
zIndex = 0
@ -133,6 +155,10 @@ open class FSPagerViewTransformer: NSObject {
attributes.transform = transform
attributes.zIndex = zIndex
case .overlap,.linear:
guard scrollDirection == .horizontal else {
// This type doesn't support vertical mode
return
}
let scale = max(1 - (1-self.minimumScale) * abs(position), self.minimumScale)
let transform = CGAffineTransform(scaleX: scale, y: scale)
attributes.transform = transform
@ -141,6 +167,10 @@ open class FSPagerViewTransformer: NSObject {
let zIndex = (1-abs(position)) * 10
attributes.zIndex = Int(zIndex)
case .coverFlow:
guard scrollDirection == .horizontal else {
// This type doesn't support vertical mode
return
}
let position = min(max(-position,-1) ,1)
let rotation = sin(position*CGFloat(M_PI_2)) * CGFloat(M_PI_4)*1.5
let translationZ = -itemSpacing * 0.5 * abs(position)
@ -151,6 +181,10 @@ open class FSPagerViewTransformer: NSObject {
attributes.zIndex = 100 - Int(abs(position))
attributes.transform3D = transform3D
case .ferrisWheel, .invertedFerrisWheel:
guard scrollDirection == .horizontal else {
// This type doesn't support vertical mode
return
}
// http://ronnqvi.st/translate-rotate-translate/
var zIndex = 0
var transform = CGAffineTransform.identity
@ -175,22 +209,34 @@ open class FSPagerViewTransformer: NSObject {
attributes.zIndex = zIndex
case .cubic:
switch position {
case -1...1:
case -CGFloat.greatestFiniteMagnitude ... -1:
attributes.alpha = 0
case -1 ..< 1:
attributes.alpha = 1
attributes.zIndex = Int((1-position) * CGFloat(10))
let direction: CGFloat = position < 0 ? 1 : -1
let theta = position * CGFloat(M_PI_2)
let width = attributes.bounds.width
// ForwardX -> RotateY -> BackwardX
attributes.center.x += direction*width*0.5 // ForwardX
let theta = position * CGFloat(M_PI_2) * (scrollDirection == .horizontal ? 1 : -1)
let radius = scrollDirection == .horizontal ? attributes.bounds.width : attributes.bounds.height
var transform3D = CATransform3DIdentity
transform3D.m34 = -0.002
transform3D = CATransform3DRotate(transform3D, theta, 0, 1, 0) // RotateY
transform3D = CATransform3DTranslate(transform3D,-direction*width*0.5, 0, 0) // BackwardX
switch scrollDirection {
case .horizontal:
// ForwardX -> RotateY -> BackwardX
attributes.center.x += direction*radius*0.5 // ForwardX
transform3D = CATransform3DRotate(transform3D, theta, 0, 1, 0) // RotateY
transform3D = CATransform3DTranslate(transform3D,-direction*radius*0.5, 0, 0) // BackwardX
case .vertical:
// ForwardY -> RotateX -> BackwardY
attributes.center.y += direction*radius*0.5 // ForwardY
transform3D = CATransform3DRotate(transform3D, theta, 1, 0, 0) // RotateX
transform3D = CATransform3DTranslate(transform3D,0, -direction*radius*0.5, 0) // BackwardY
}
attributes.transform3D = transform3D
default:
attributes.zIndex = 0
case 1 ... CGFloat.greatestFiniteMagnitude:
attributes.alpha = 0
default:
attributes.alpha = 0
attributes.zIndex = 0
}
}
}
@ -200,14 +246,27 @@ open class FSPagerViewTransformer: NSObject {
guard let pagerView = self.pagerView else {
return 0
}
let scrollDirection = pagerView.scrollDirection
switch self.type {
case .overlap:
guard scrollDirection == .horizontal else {
return 0
}
return pagerView.itemSize.width * -self.minimumScale * 0.6
case .linear:
guard scrollDirection == .horizontal else {
return 0
}
return pagerView.itemSize.width * -self.minimumScale * 0.2
case .coverFlow:
guard scrollDirection == .horizontal else {
return 0
}
return -pagerView.itemSize.width * sin(CGFloat(M_PI_4)/4.0*3.0)
case .ferrisWheel,.invertedFerrisWheel:
guard scrollDirection == .horizontal else {
return 0
}
return -pagerView.itemSize.width * 0.15
case .cubic:
return 0

View File

@ -12,7 +12,7 @@ import UIKit
class FSPagerViewCollectionView: UICollectionView {
fileprivate weak var pagerView: FSPagerView? {
fileprivate var pagerView: FSPagerView? {
return self.superview?.superview as? FSPagerView
}

View File

@ -74,6 +74,12 @@ public protocol FSPagerViewDelegate: NSObjectProtocol {
}
@objc
public enum FSPagerViewScrollDirection: Int {
case horizontal
case vertical
}
@IBDesignable
open class FSPagerView: UIView,UICollectionViewDataSource,UICollectionViewDelegate {
@ -87,7 +93,14 @@ open class FSPagerView: UIView,UICollectionViewDataSource,UICollectionViewDelega
open weak var dataSource: FSPagerViewDataSource?
open weak var delegate: FSPagerViewDelegate?
#endif
/// The scroll direction of the pager view. Default is horizontal.
open var scrollDirection: FSPagerViewScrollDirection = .horizontal {
didSet {
self.collectionViewLayout.forceInvalidate()
}
}
/// The time interval of automatic sliding. 0 means disabling automatic sliding. Default is 0.
@IBInspectable
open var automaticSlidingInterval: CGFloat = 0.0 {
@ -119,8 +132,8 @@ open class FSPagerView: UIView,UICollectionViewDataSource,UICollectionViewDelega
@IBInspectable
open var isInfinite: Bool = false {
didSet {
self.collectionViewLayout.needsReprepare = true
self.collectionView.reloadData()
self.collectionViewLayout.forceInvalidate()
}
}
@ -156,7 +169,8 @@ open class FSPagerView: UIView,UICollectionViewDataSource,UICollectionViewDelega
/// The percentage of x position at which the origin of the content view is offset from the origin of the pagerView view.
open var scrollOffset: CGFloat {
let scrollOffset = Double(self.collectionView.contentOffset.x.divided(by: self.collectionViewLayout.itemSpacing))
let contentOffset = max(self.collectionView.contentOffset.x, self.collectionView.contentOffset.y)
let scrollOffset = Double(contentOffset.divided(by: self.collectionViewLayout.itemSpacing))
return fmod(CGFloat(scrollOffset), CGFloat(Double(self.numberOfItems)))
}
@ -179,13 +193,23 @@ open class FSPagerView: UIView,UICollectionViewDataSource,UICollectionViewDelega
fileprivate var dequeingSection = 0
fileprivate var centermostIndexPath: IndexPath {
guard self.numberOfItems > 0, self.collectionView.contentSize.width > 0 else {
guard self.numberOfItems > 0, self.collectionView.contentSize != .zero else {
return IndexPath(item: 0, section: 0)
}
let sortedIndexPaths = self.collectionView.indexPathsForVisibleItems.sorted { (l, r) -> Bool in
let leftCenter = self.collectionViewLayout.frame(for: l).midX
let rightCenter = self.collectionViewLayout.frame(for: r).midX
let ruler = self.collectionView.bounds.midX
let leftFrame = self.collectionViewLayout.frame(for: l)
let rightFrame = self.collectionViewLayout.frame(for: r)
var leftCenter: CGFloat,rightCenter: CGFloat,ruler: CGFloat
switch self.scrollDirection {
case .horizontal:
leftCenter = leftFrame.midX
rightCenter = rightFrame.midX
ruler = self.collectionView.bounds.midX
case .vertical:
leftCenter = leftFrame.midY
rightCenter = rightFrame.midY
ruler = self.collectionView.bounds.midY
}
return abs(ruler-leftCenter) < abs(ruler-rightCenter)
}
let indexPath = sortedIndexPaths.first
@ -344,7 +368,8 @@ open class FSPagerView: UIView,UICollectionViewDataSource,UICollectionViewDelega
public func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
if let function = self.delegate?.pagerViewWillEndDragging(_:targetIndex:) {
let targetItem = lround(Double(targetContentOffset.pointee.x/self.collectionViewLayout.itemSpacing))
let contentOffset = self.scrollDirection == .horizontal ? targetContentOffset.pointee.x : targetContentOffset.pointee.y
let targetItem = lround(Double(contentOffset/self.collectionViewLayout.itemSpacing))
function(self, targetItem % self.numberOfItems)
}
if self.automaticSlidingInterval > 0 {
@ -417,7 +442,8 @@ open class FSPagerView: UIView,UICollectionViewDataSource,UICollectionViewDelega
@objc(selectItemAtIndex:animated:)
open func selectItem(at index: Int, animated: Bool) {
let indexPath = self.nearbyIndexPath(for: index)
self.collectionView.selectItem(at: indexPath, animated: animated, scrollPosition: .centeredHorizontally)
let scrollPosition: UICollectionViewScrollPosition = self.scrollDirection == .horizontal ? .centeredVertically : .centeredVertically
self.collectionView.selectItem(at: indexPath, animated: animated, scrollPosition: scrollPosition)
}
/// Deselects the item at the specified index.

View File

@ -11,7 +11,6 @@ import UIKit
open class FSPagerViewLayoutAttributes: UICollectionViewLayoutAttributes {
open var position: CGFloat = 0
open var interitemSpacing: CGFloat = 0
open override func isEqual(_ object: Any?) -> Bool {
guard let object = object as? FSPagerViewLayoutAttributes else {
@ -19,14 +18,12 @@ open class FSPagerViewLayoutAttributes: UICollectionViewLayoutAttributes {
}
var isEqual = super.isEqual(object)
isEqual = isEqual && (self.position == object.position)
isEqual = isEqual && (self.interitemSpacing == object.interitemSpacing)
return isEqual
}
open override func copy(with zone: NSZone? = nil) -> Any {
let copy = super.copy(with: zone) as! FSPagerViewLayoutAttributes
copy.position = self.position
copy.interitemSpacing = self.interitemSpacing
return copy
}