diff --git a/FSPagerView.podspec b/FSPagerView.podspec
index 2087852..7bf3605 100644
--- a/FSPagerView.podspec
+++ b/FSPagerView.podspec
@@ -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"
diff --git a/FSPagerView/FSPagerView/Info.plist b/FSPagerView/FSPagerView/Info.plist
index 0d6341f..a6faa05 100644
--- a/FSPagerView/FSPagerView/Info.plist
+++ b/FSPagerView/FSPagerView/Info.plist
@@ -15,7 +15,7 @@
CFBundlePackageType
FMWK
CFBundleShortVersionString
- 0.3.0
+ 0.4.0
CFBundleVersion
$(CURRENT_PROJECT_VERSION)
NSPrincipalClass
diff --git a/FSPagerViewExample-Objc/FSPagerViewExample-Objc.xcodeproj/xcuserdata/wenchaoding.xcuserdatad/xcschemes/xcschememanagement.plist b/FSPagerViewExample-Objc/FSPagerViewExample-Objc.xcodeproj/xcuserdata/wenchaoding.xcuserdatad/xcschemes/xcschememanagement.plist
index 44177a1..7a2ae77 100644
--- a/FSPagerViewExample-Objc/FSPagerViewExample-Objc.xcodeproj/xcuserdata/wenchaoding.xcuserdatad/xcschemes/xcschememanagement.plist
+++ b/FSPagerViewExample-Objc/FSPagerViewExample-Objc.xcodeproj/xcuserdata/wenchaoding.xcuserdatad/xcschemes/xcschememanagement.plist
@@ -7,7 +7,7 @@
FSPagerViewExample-Objc.xcscheme
orderHint
- 0
+ 1
SuppressBuildableAutocreation
diff --git a/FSPagerViewExamples.xcworkspace/contents.xcworkspacedata b/FSPagerViewExamples.xcworkspace/contents.xcworkspacedata
index 56c48f2..db5ee4a 100644
--- a/FSPagerViewExamples.xcworkspace/contents.xcworkspacedata
+++ b/FSPagerViewExamples.xcworkspace/contents.xcworkspacedata
@@ -7,4 +7,7 @@
+
+
diff --git a/README-OBJECTIVE-C.md b/README-OBJECTIVE-C.md
index 5fe88fc..92db05e 100644
--- a/README-OBJECTIVE-C.md
+++ b/README-OBJECTIVE-C.md
@@ -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];
*
***[FSCalendar](https://github.com/WenchaoD/FSCalendar)***
+---
+# [Documentation](http://cocoadocs.org/docsets/FSPagerView)
\ No newline at end of file
diff --git a/README.md b/README.md
index 266bcef..1911e42 100644
--- a/README.md
+++ b/README.md
@@ -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)
*
***[FSCalendar](https://github.com/WenchaoD/FSCalendar)***
+---
-
+# [Documentation](http://cocoadocs.org/docsets/FSPagerView)
\ No newline at end of file
diff --git a/Sources/FSPageViewLayout.swift b/Sources/FSPageViewLayout.swift
index 5413143..cd81d46 100644
--- a/Sources/FSPageViewLayout.swift
+++ b/Sources/FSPageViewLayout.swift
@@ -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)
}
diff --git a/Sources/FSPageViewTransformer.swift b/Sources/FSPageViewTransformer.swift
index b815f61..946d7fe 100644
--- a/Sources/FSPageViewTransformer.swift
+++ b/Sources/FSPageViewTransformer.swift
@@ -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
diff --git a/Sources/FSPagerCollectionView.swift b/Sources/FSPagerCollectionView.swift
index a0e08a0..780733e 100644
--- a/Sources/FSPagerCollectionView.swift
+++ b/Sources/FSPagerCollectionView.swift
@@ -12,7 +12,7 @@ import UIKit
class FSPagerViewCollectionView: UICollectionView {
- fileprivate weak var pagerView: FSPagerView? {
+ fileprivate var pagerView: FSPagerView? {
return self.superview?.superview as? FSPagerView
}
diff --git a/Sources/FSPagerView.swift b/Sources/FSPagerView.swift
index 1d0ed0c..2182ce1 100644
--- a/Sources/FSPagerView.swift
+++ b/Sources/FSPagerView.swift
@@ -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) {
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.
diff --git a/Sources/FSPagerViewLayoutAttributes.swift b/Sources/FSPagerViewLayoutAttributes.swift
index 06b4396..d93cb33 100644
--- a/Sources/FSPagerViewLayoutAttributes.swift
+++ b/Sources/FSPagerViewLayoutAttributes.swift
@@ -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
}