Skip to content

Commit

Permalink
Add 'pagingDistance' property to FSPagerView.
Browse files Browse the repository at this point in the history
  • Loading branch information
WenchaoD committed Sep 19, 2018
1 parent 396cea1 commit 76f544f
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
/* End PBXContainerItemProxy section */

/* Begin PBXFileReference section */
50989DFE2151DB29004DBB4A /* FSPagerViewObjcCompat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FSPagerViewObjcCompat.h; sourceTree = "<group>"; };
F95483991E625F1E0069FD7E /* FSPagerViewLayoutAttributes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FSPagerViewLayoutAttributes.swift; sourceTree = "<group>"; };
F9580B511E5D995400C5B267 /* FSPageControl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FSPageControl.swift; sourceTree = "<group>"; };
F9580B521E5D995400C5B267 /* FSPagerCollectionView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FSPagerCollectionView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -99,6 +100,7 @@
F9580B551E5D995400C5B267 /* FSPageViewLayout.swift */,
F9580B561E5D995400C5B267 /* FSPageViewTransformer.swift */,
F95483991E625F1E0069FD7E /* FSPagerViewLayoutAttributes.swift */,
50989DFE2151DB29004DBB4A /* FSPagerViewObjcCompat.h */,
);
name = Sources;
path = ../Sources;
Expand Down
4 changes: 4 additions & 0 deletions FSPagerView/FSPagerView.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
objects = {

/* Begin PBXBuildFile section */
50C44A1D2150E7800093B3E9 /* FSPagerViewObjcCompat.h in Headers */ = {isa = PBXBuildFile; fileRef = 50C44A1C2150E7800093B3E9 /* FSPagerViewObjcCompat.h */; };
F9580B7B1E5D9F0600C5B267 /* FSPagerView.h in Headers */ = {isa = PBXBuildFile; fileRef = F9580B791E5D9F0600C5B267 /* FSPagerView.h */; settings = {ATTRIBUTES = (Public, ); }; };
F9580B881E5D9F2B00C5B267 /* FSPageControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9580B821E5D9F2B00C5B267 /* FSPageControl.swift */; };
F9580B891E5D9F2B00C5B267 /* FSPagerCollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9580B831E5D9F2B00C5B267 /* FSPagerCollectionView.swift */; };
Expand All @@ -18,6 +19,7 @@
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
50C44A1C2150E7800093B3E9 /* FSPagerViewObjcCompat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FSPagerViewObjcCompat.h; sourceTree = "<group>"; };
F9580B761E5D9F0600C5B267 /* FSPagerView.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FSPagerView.framework; sourceTree = BUILT_PRODUCTS_DIR; };
F9580B791E5D9F0600C5B267 /* FSPagerView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FSPagerView.h; sourceTree = "<group>"; };
F9580B7A1E5D9F0600C5B267 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
Expand Down Expand Up @@ -77,6 +79,7 @@
F9580B861E5D9F2B00C5B267 /* FSPageViewLayout.swift */,
F9D7BD291E63DD5F003F6A0E /* FSPagerViewLayoutAttributes.swift */,
F9580B871E5D9F2B00C5B267 /* FSPageViewTransformer.swift */,
50C44A1C2150E7800093B3E9 /* FSPagerViewObjcCompat.h */,
);
name = Sources;
path = ../Sources;
Expand All @@ -90,6 +93,7 @@
buildActionMask = 2147483647;
files = (
F9580B7B1E5D9F0600C5B267 /* FSPagerView.h in Headers */,
50C44A1D2150E7800093B3E9 /* FSPagerViewObjcCompat.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
/* End PBXContainerItemProxy section */

/* Begin PBXFileReference section */
50989DFD2151DB25004DBB4A /* FSPagerViewObjcCompat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FSPagerViewObjcCompat.h; sourceTree = "<group>"; };
F908BC321E35AAE4002B2F51 /* 1.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = 1.jpg; sourceTree = "<group>"; };
F908BC3A1E35AAE4002B2F51 /* 2.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = 2.jpg; sourceTree = "<group>"; };
F908BC3B1E35AAE4002B2F51 /* 3.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = 3.jpg; sourceTree = "<group>"; };
Expand Down Expand Up @@ -121,6 +122,7 @@
F9580B621E5D997200C5B267 /* FSPageViewLayout.swift */,
F9FF349E1E65B38C001E943F /* FSPagerViewLayoutAttributes.swift */,
F9580B631E5D997200C5B267 /* FSPageViewTransformer.swift */,
50989DFD2151DB25004DBB4A /* FSPagerViewObjcCompat.h */,
);
name = Sources;
path = ../Sources;
Expand Down
52 changes: 31 additions & 21 deletions Sources/FSPageViewLayout.swift
Original file line number Diff line number Diff line change
Expand Up @@ -151,39 +151,49 @@ class FSPagerViewLayout: UICollectionViewLayout {
}

override open func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {
guard let collectionView = self.collectionView else {
guard let collectionView = self.collectionView, let pagerView = self.pagerView else {
return proposedContentOffset
}
var proposedContentOffset = proposedContentOffset
let touchedContentOffset: CGPoint = collectionView.panGestureRecognizer.location(in: collectionView)

func calculateTargetOffset(by proposedOffset: CGFloat, touchedOffset: CGFloat, boundedOffset: CGFloat) -> CGFloat {
var targetOffset: CGFloat
if pagerView.pagingDistance == FSPagerViewAutomaticPagingDistance {
if abs(velocity.x) >= 0.3 {
let vector: CGFloat = velocity.x >= 0 ? 1.0 : -1.0
targetOffset = round(proposedOffset/self.itemSpacing+0.35*vector) * self.itemSpacing // Ceil by 0.15, rather than 0.5
} else {
targetOffset = round(proposedOffset/self.itemSpacing) * self.itemSpacing
}
} else {
let extraDistance = max(pagerView.pagingDistance-1, 0)
switch velocity.x {
case 0.3 ... CGFloat.greatestFiniteMagnitude:
targetOffset = ceil(touchedOffset/self.itemSpacing+CGFloat(extraDistance)) * self.itemSpacing
case -CGFloat.greatestFiniteMagnitude ... -0.3:
targetOffset = floor(touchedOffset/self.itemSpacing-1-CGFloat(extraDistance)) * self.itemSpacing
default:
targetOffset = round(proposedOffset/self.itemSpacing) * self.itemSpacing
}
}
targetOffset = max(0, targetOffset)
targetOffset = min(boundedOffset, targetOffset)
return targetOffset
}
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)
let originalContentOffsetX = collectionView.contentOffset.x - translation
if abs(translation) <= minFlippingDistance {
if abs(velocity.x) >= 0.3 && abs(proposedContentOffset.x-originalContentOffsetX) <= self.itemSpacing*0.5 {
offset += self.itemSpacing * (velocity.x)/abs(velocity.x)
}
}
return offset
let boundedOffset = collectionView.contentSize.width-self.itemSpacing
return calculateTargetOffset(by: proposedContentOffset.x, touchedOffset: touchedContentOffset.x, boundedOffset: boundedOffset)
}()
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
let boundedOffset = collectionView.contentSize.height-self.itemSpacing
return calculateTargetOffset(by: proposedContentOffset.y, touchedOffset: touchedContentOffset.y, boundedOffset: boundedOffset)
}()
proposedContentOffset = CGPoint(x: proposedContentOffsetX, y: proposedContentOffsetY)
return proposedContentOffset
Expand Down
7 changes: 7 additions & 0 deletions Sources/FSPagerView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ public enum FSPagerViewScrollDirection: Int {
case vertical
}

/// The paging distance is automatically calculated according to the scrolling speed of the pager view.
public let FSPagerViewAutomaticPagingDistance: UInt = 0

@IBDesignable
open class FSPagerView: UIView,UICollectionViewDataSource,UICollectionViewDelegate {

Expand Down Expand Up @@ -138,6 +141,10 @@ open class FSPagerView: UIView,UICollectionViewDataSource,UICollectionViewDelega
}
}

/// An unsigned integer value that determines the paging distance of the pager view, which indicates the number of passing items during a single paging. When the value of this property is FSPagerViewAutomaticPagingDistance(0), the actual 'distance' is automatically calculated according to the scrolling speed of the pager view. Default is 1.
@IBInspectable
open var pagingDistance: UInt = 1

/// A Boolean value that determines whether bouncing always occurs when horizontal scrolling reaches the end of the content view.
@IBInspectable
open var alwaysBounceHorizontal: Bool {
Expand Down
9 changes: 9 additions & 0 deletions Sources/FSPagerViewObjcCompat.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//
// FSPagerViewObjcCompat.h
// FSPagerView
//
// Created by 丁文超 on 2018/9/18.
// Copyright © 2018 Wenchao Ding. All rights reserved.
//

#define FSPagerViewAutomaticPagingDistance 0

0 comments on commit 76f544f

Please sign in to comment.