Add 'pagingDistance' property to FSPagerView.
This commit is contained in:
parent
396cea13e4
commit
76f544f456
|
|
@ -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>"; };
|
||||
|
|
@ -99,6 +100,7 @@
|
|||
F9580B551E5D995400C5B267 /* FSPageViewLayout.swift */,
|
||||
F9580B561E5D995400C5B267 /* FSPageViewTransformer.swift */,
|
||||
F95483991E625F1E0069FD7E /* FSPagerViewLayoutAttributes.swift */,
|
||||
50989DFE2151DB29004DBB4A /* FSPagerViewObjcCompat.h */,
|
||||
);
|
||||
name = Sources;
|
||||
path = ../Sources;
|
||||
|
|
|
|||
|
|
@ -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 */; };
|
||||
|
|
@ -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>"; };
|
||||
|
|
@ -77,6 +79,7 @@
|
|||
F9580B861E5D9F2B00C5B267 /* FSPageViewLayout.swift */,
|
||||
F9D7BD291E63DD5F003F6A0E /* FSPagerViewLayoutAttributes.swift */,
|
||||
F9580B871E5D9F2B00C5B267 /* FSPageViewTransformer.swift */,
|
||||
50C44A1C2150E7800093B3E9 /* FSPagerViewObjcCompat.h */,
|
||||
);
|
||||
name = Sources;
|
||||
path = ../Sources;
|
||||
|
|
@ -90,6 +93,7 @@
|
|||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
F9580B7B1E5D9F0600C5B267 /* FSPagerView.h in Headers */,
|
||||
50C44A1D2150E7800093B3E9 /* FSPagerViewObjcCompat.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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>"; };
|
||||
|
|
@ -121,6 +122,7 @@
|
|||
F9580B621E5D997200C5B267 /* FSPageViewLayout.swift */,
|
||||
F9FF349E1E65B38C001E943F /* FSPagerViewLayoutAttributes.swift */,
|
||||
F9580B631E5D997200C5B267 /* FSPageViewTransformer.swift */,
|
||||
50989DFD2151DB25004DBB4A /* FSPagerViewObjcCompat.h */,
|
||||
);
|
||||
name = Sources;
|
||||
path = ../Sources;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
||||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
//
|
||||
// FSPagerViewObjcCompat.h
|
||||
// FSPagerView
|
||||
//
|
||||
// Created by 丁文超 on 2018/9/18.
|
||||
// Copyright © 2018 Wenchao Ding. All rights reserved.
|
||||
//
|
||||
|
||||
#define FSPagerViewAutomaticPagingDistance 0
|
||||
Loading…
Reference in New Issue