Compare commits
67 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
795308668c | |
|
|
f3e95c90ec | |
|
|
320b4f57bb | |
|
|
0df6070810 | |
|
|
c1718fb5c1 | |
|
|
9bebb56fc1 | |
|
|
15a64b5c3f | |
|
|
bd38b12314 | |
|
|
00dd915191 | |
|
|
aa652bfe05 | |
|
|
68b82f91e1 | |
|
|
3acbd3e987 | |
|
|
0560602b2f | |
|
|
1c2aaef6bf | |
|
|
977ac1f5cf | |
|
|
a67e26d75d | |
|
|
fba5e9ea70 | |
|
|
d25867705f | |
|
|
ca03ae6475 | |
|
|
7a1eac8f0a | |
|
|
6b4a11fa78 | |
|
|
e61151be2f | |
|
|
2f16b6f98f | |
|
|
e535eb1a81 | |
|
|
13669bf75a | |
|
|
99cdb1d720 | |
|
|
bc6e469f52 | |
|
|
e263e4ad31 | |
|
|
ef42e06bde | |
|
|
ebae2a5c73 | |
|
|
08daae1d4c | |
|
|
3711f2998d | |
|
|
a7a57e2edd | |
|
|
0c776994db | |
|
|
d3544d8076 | |
|
|
c72899860d | |
|
|
b5fc6ccbfc | |
|
|
a50ca2dadf | |
|
|
ba3f58f953 | |
|
|
e70c8a3c9b | |
|
|
29aa05da07 | |
|
|
8ebbb0efac | |
|
|
f0e653435e | |
|
|
f3b4c98b99 | |
|
|
452486b098 | |
|
|
130c99c1bb | |
|
|
6b54500113 | |
|
|
45f1a6c11b | |
|
|
985890d382 | |
|
|
f280708f52 | |
|
|
7167dacf0b | |
|
|
2547a9957c | |
|
|
bb03aeb48b | |
|
|
76f544f456 | |
|
|
396cea13e4 | |
|
|
7aad89b419 | |
|
|
515068d176 | |
|
|
8d40e06b87 | |
|
|
a7a5b14a1a | |
|
|
61086f0806 | |
|
|
7fab78be1b | |
|
|
fd70d6b91e | |
|
|
20f43bc831 | |
|
|
3537a975af | |
|
|
b96ab55965 | |
|
|
6085e2443c | |
|
|
70d99b4e79 |
|
|
@ -65,4 +65,6 @@ Carthage/Build
|
|||
fastlane/report.xml
|
||||
fastlane/Preview.html
|
||||
fastlane/screenshots
|
||||
fastlane/test_output
|
||||
fastlane/test_output
|
||||
|
||||
Index/*
|
||||
|
|
@ -1 +0,0 @@
|
|||
4.0
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
|
@ -7,6 +7,7 @@
|
|||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
F931E00C2158A1F3001B2A01 /* FSPagerViewObjcCompat.m in Sources */ = {isa = PBXBuildFile; fileRef = F931E00B2158A1F3001B2A01 /* FSPagerViewObjcCompat.m */; };
|
||||
F954839A1E625F1E0069FD7E /* FSPagerViewLayoutAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = F95483991E625F1E0069FD7E /* FSPagerViewLayoutAttributes.swift */; };
|
||||
F954839B1E625F1E0069FD7E /* FSPagerViewLayoutAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = F95483991E625F1E0069FD7E /* FSPagerViewLayoutAttributes.swift */; };
|
||||
F9580B571E5D995400C5B267 /* FSPageControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9580B511E5D995400C5B267 /* FSPageControl.swift */; };
|
||||
|
|
@ -43,6 +44,8 @@
|
|||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
50989DFE2151DB29004DBB4A /* FSPagerViewObjcCompat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FSPagerViewObjcCompat.h; sourceTree = "<group>"; };
|
||||
F931E00B2158A1F3001B2A01 /* FSPagerViewObjcCompat.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FSPagerViewObjcCompat.m; 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 +102,8 @@
|
|||
F9580B551E5D995400C5B267 /* FSPageViewLayout.swift */,
|
||||
F9580B561E5D995400C5B267 /* FSPageViewTransformer.swift */,
|
||||
F95483991E625F1E0069FD7E /* FSPagerViewLayoutAttributes.swift */,
|
||||
50989DFE2151DB29004DBB4A /* FSPagerViewObjcCompat.h */,
|
||||
F931E00B2158A1F3001B2A01 /* FSPagerViewObjcCompat.m */,
|
||||
);
|
||||
name = Sources;
|
||||
path = ../Sources;
|
||||
|
|
@ -216,7 +221,7 @@
|
|||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 0820;
|
||||
LastUpgradeCheck = 0900;
|
||||
LastUpgradeCheck = 1030;
|
||||
ORGANIZATIONNAME = "Wenchao Ding";
|
||||
TargetAttributes = {
|
||||
F97C96761E1FDE25002D9E7E = {
|
||||
|
|
@ -236,7 +241,7 @@
|
|||
};
|
||||
buildConfigurationList = F97C96721E1FDE25002D9E7E /* Build configuration list for PBXProject "FSPagerViewExample" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
|
|
@ -296,6 +301,7 @@
|
|||
F9C694331E40C583007084B6 /* BasicExampleViewController.swift in Sources */,
|
||||
F9580B5A1E5D995400C5B267 /* FSPagerViewCell.swift in Sources */,
|
||||
F9580B5B1E5D995400C5B267 /* FSPageViewLayout.swift in Sources */,
|
||||
F931E00C2158A1F3001B2A01 /* FSPagerViewObjcCompat.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
@ -342,6 +348,7 @@
|
|||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
|
|
@ -351,6 +358,7 @@
|
|||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
|
|
@ -358,6 +366,7 @@
|
|||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
|
|
@ -390,6 +399,7 @@
|
|||
SDKROOT = iphoneos;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
|
|
@ -398,6 +408,7 @@
|
|||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
|
|
@ -407,6 +418,7 @@
|
|||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
|
|
@ -414,6 +426,7 @@
|
|||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
|
|
@ -438,6 +451,7 @@
|
|||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
|
|
@ -452,8 +466,8 @@
|
|||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.wenchaod.FSPagerViewExample;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.0;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
|
|
@ -466,8 +480,8 @@
|
|||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.wenchaod.FSPagerViewExample;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.0;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
|
|
@ -480,8 +494,8 @@
|
|||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.wenchaod.FSPagerViewExampleUITests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = On;
|
||||
SWIFT_VERSION = 4.0;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TEST_TARGET_NAME = FSPagerViewExample;
|
||||
};
|
||||
name = Debug;
|
||||
|
|
@ -495,8 +509,8 @@
|
|||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.wenchaod.FSPagerViewExampleUITests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = On;
|
||||
SWIFT_VERSION = 4.0;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TEST_TARGET_NAME = FSPagerViewExample;
|
||||
};
|
||||
name = Release;
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
|||
var window: UIWindow?
|
||||
|
||||
|
||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
|
||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
||||
// Override point for customization after application launch.
|
||||
return true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,8 +10,9 @@ import UIKit
|
|||
|
||||
class BasicExampleViewController: UIViewController,UITableViewDataSource,UITableViewDelegate,FSPagerViewDataSource,FSPagerViewDelegate {
|
||||
|
||||
fileprivate let sectionTitles = ["Configurations", "Item Size", "Interitem Spacing", "Number Of Items"]
|
||||
fileprivate let sectionTitles = ["Configurations", "Decelaration Distance", "Item Size", "Interitem Spacing", "Number Of Items"]
|
||||
fileprivate let configurationTitles = ["Automatic sliding","Infinite"]
|
||||
fileprivate let decelerationDistanceOptions = ["Automatic", "1", "2"]
|
||||
fileprivate let imageNames = ["1.jpg","2.jpg","3.jpg","4.jpg","5.jpg","6.jpg","7.jpg"]
|
||||
fileprivate var numberOfItems = 7
|
||||
|
||||
|
|
@ -19,7 +20,7 @@ class BasicExampleViewController: UIViewController,UITableViewDataSource,UITable
|
|||
@IBOutlet weak var pagerView: FSPagerView! {
|
||||
didSet {
|
||||
self.pagerView.register(FSPagerViewCell.self, forCellWithReuseIdentifier: "cell")
|
||||
self.pagerView.itemSize = .zero
|
||||
self.pagerView.itemSize = FSPagerView.automaticSize
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -37,17 +38,17 @@ class BasicExampleViewController: UIViewController,UITableViewDataSource,UITable
|
|||
return self.sectionTitles.count
|
||||
}
|
||||
|
||||
@available(iOS 2.0, *)
|
||||
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
switch section {
|
||||
case 0:
|
||||
return self.configurationTitles.count
|
||||
case 1,2,3:
|
||||
case 1:
|
||||
return self.decelerationDistanceOptions.count
|
||||
case 2,3,4:
|
||||
return 1
|
||||
default:
|
||||
break
|
||||
return 0
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
|
|
@ -65,10 +66,25 @@ class BasicExampleViewController: UIViewController,UITableViewDataSource,UITable
|
|||
}
|
||||
return cell
|
||||
case 1:
|
||||
// Decelaration Distance
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: "cell")!
|
||||
cell.textLabel?.text = self.decelerationDistanceOptions[indexPath.row]
|
||||
switch indexPath.row {
|
||||
case 0:
|
||||
cell.accessoryType = self.pagerView.decelerationDistance == FSPagerView.automaticDistance ? .checkmark : .none
|
||||
case 1:
|
||||
cell.accessoryType = self.pagerView.decelerationDistance == 1 ? .checkmark : .none
|
||||
case 2:
|
||||
cell.accessoryType = self.pagerView.decelerationDistance == 2 ? .checkmark : .none
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return cell;
|
||||
case 2:
|
||||
// Item Spacing
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: "slider_cell")!
|
||||
let slider = cell.contentView.subviews.first as! UISlider
|
||||
slider.tag = indexPath.section
|
||||
slider.tag = 1
|
||||
slider.value = {
|
||||
let scale: CGFloat = self.pagerView.itemSize.width/self.pagerView.frame.width
|
||||
let value: CGFloat = (0.5-scale)*2
|
||||
|
|
@ -76,19 +92,19 @@ class BasicExampleViewController: UIViewController,UITableViewDataSource,UITable
|
|||
}()
|
||||
slider.isContinuous = true
|
||||
return cell
|
||||
case 2:
|
||||
case 3:
|
||||
// Interitem Spacing
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: "slider_cell")!
|
||||
let slider = cell.contentView.subviews.first as! UISlider
|
||||
slider.tag = indexPath.section
|
||||
slider.tag = 2
|
||||
slider.value = Float(self.pagerView.interitemSpacing/20.0)
|
||||
slider.isContinuous = true
|
||||
return cell
|
||||
case 3:
|
||||
case 4:
|
||||
// Number Of Items
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: "slider_cell")!
|
||||
let slider = cell.contentView.subviews.first as! UISlider
|
||||
slider.tag = indexPath.section
|
||||
slider.tag = 3
|
||||
slider.minimumValue = 1.0 / 7
|
||||
slider.maximumValue = 1.0
|
||||
slider.value = Float(self.numberOfItems) / 7.0
|
||||
|
|
@ -103,7 +119,7 @@ class BasicExampleViewController: UIViewController,UITableViewDataSource,UITable
|
|||
// MARK:- UITableViewDelegate
|
||||
|
||||
func tableView(_ tableView: UITableView, shouldHighlightRowAt indexPath: IndexPath) -> Bool {
|
||||
return indexPath.section == 0
|
||||
return indexPath.section == 0 || indexPath.section == 1
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
|
|
@ -116,6 +132,18 @@ class BasicExampleViewController: UIViewController,UITableViewDataSource,UITable
|
|||
self.pagerView.isInfinite = !self.pagerView.isInfinite
|
||||
}
|
||||
tableView.reloadSections([indexPath.section], with: .automatic)
|
||||
case 1:
|
||||
switch indexPath.row {
|
||||
case 0:
|
||||
self.pagerView.decelerationDistance = FSPagerView.automaticDistance
|
||||
case 1:
|
||||
self.pagerView.decelerationDistance = 1
|
||||
case 2:
|
||||
self.pagerView.decelerationDistance = 2
|
||||
default:
|
||||
break
|
||||
}
|
||||
tableView.reloadSections([indexPath.section], with: .automatic)
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
|
@ -149,14 +177,14 @@ class BasicExampleViewController: UIViewController,UITableViewDataSource,UITable
|
|||
func pagerView(_ pagerView: FSPagerView, didSelectItemAt index: Int) {
|
||||
pagerView.deselectItem(at: index, animated: true)
|
||||
pagerView.scrollToItem(at: index, animated: true)
|
||||
self.pageControl.currentPage = index
|
||||
}
|
||||
|
||||
func pagerViewDidScroll(_ pagerView: FSPagerView) {
|
||||
guard self.pageControl.currentPage != pagerView.currentIndex else {
|
||||
return
|
||||
}
|
||||
self.pageControl.currentPage = pagerView.currentIndex // Or Use KVO with property "currentIndex"
|
||||
func pagerViewWillEndDragging(_ pagerView: FSPagerView, targetIndex: Int) {
|
||||
self.pageControl.currentPage = targetIndex
|
||||
}
|
||||
|
||||
func pagerViewDidEndScrollAnimation(_ pagerView: FSPagerView) {
|
||||
self.pageControl.currentPage = pagerView.currentIndex
|
||||
}
|
||||
|
||||
@IBAction func sliderValueChanged(_ sender: UISlider) {
|
||||
|
|
|
|||
|
|
@ -228,11 +228,8 @@ class PageControlExampleViewController: UIViewController,UITableViewDataSource,U
|
|||
|
||||
// MARK:- FSPagerViewDelegate
|
||||
|
||||
func pagerViewDidScroll(_ pagerView: FSPagerView) {
|
||||
guard self.pageControl.currentPage != pagerView.currentIndex else {
|
||||
return
|
||||
}
|
||||
self.pageControl.currentPage = pagerView.currentIndex // Or Use KVO with property "currentIndex"
|
||||
func pagerViewWillEndDragging(_ pagerView: FSPagerView, targetIndex: Int) {
|
||||
self.pageControl.currentPage = targetIndex
|
||||
}
|
||||
|
||||
// MARK:- Target Actions
|
||||
|
|
|
|||
|
|
@ -27,17 +27,22 @@ class TransformerExampleViewController: UIViewController,FSPagerViewDataSource,F
|
|||
self.pagerView.transformer = FSPagerViewTransformer(type:type)
|
||||
switch type {
|
||||
case .crossFading, .zoomOut, .depth:
|
||||
self.pagerView.itemSize = .zero // 'Zero' means fill the size of parent
|
||||
self.pagerView.itemSize = FSPagerView.automaticSize
|
||||
self.pagerView.decelerationDistance = 1
|
||||
case .linear, .overlap:
|
||||
let transform = CGAffineTransform(scaleX: 0.6, y: 0.75)
|
||||
self.pagerView.itemSize = self.pagerView.frame.size.applying(transform)
|
||||
self.pagerView.decelerationDistance = FSPagerView.automaticDistance
|
||||
case .ferrisWheel, .invertedFerrisWheel:
|
||||
self.pagerView.itemSize = CGSize(width: 180, height: 140)
|
||||
self.pagerView.decelerationDistance = FSPagerView.automaticDistance
|
||||
case .coverFlow:
|
||||
self.pagerView.itemSize = CGSize(width: 220, height: 170)
|
||||
self.pagerView.decelerationDistance = FSPagerView.automaticDistance
|
||||
case .cubic:
|
||||
let transform = CGAffineTransform(scaleX: 0.9, y: 0.9)
|
||||
self.pagerView.itemSize = self.pagerView.frame.size.applying(transform)
|
||||
self.pagerView.decelerationDistance = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -108,5 +113,3 @@ class TransformerExampleViewController: UIViewController,FSPagerViewDataSource,F
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
Pod::Spec.new do |s|
|
||||
|
||||
s.name = "FSPagerView"
|
||||
s.version = "0.7.2"
|
||||
s.version = "0.8.3"
|
||||
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"
|
||||
|
|
@ -14,6 +14,8 @@ Pod::Spec.new do |s|
|
|||
s.ios.deployment_target = '8.0'
|
||||
s.requires_arc = true
|
||||
s.framework = 'UIKit'
|
||||
s.source_files = 'Sources/*.swift'
|
||||
s.source_files = 'Sources/*.{swift,h,m}'
|
||||
s.swift_version = '5.0'
|
||||
s.cocoapods_version = '>= 1.4.0'
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@
|
|||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
50C44A1D2150E7800093B3E9 /* FSPagerViewObjcCompat.h in Headers */ = {isa = PBXBuildFile; fileRef = 50C44A1C2150E7800093B3E9 /* FSPagerViewObjcCompat.h */; };
|
||||
F931E0062158A062001B2A01 /* FSPagerViewObjcCompat.m in Sources */ = {isa = PBXBuildFile; fileRef = F931E0052158A062001B2A01 /* FSPagerViewObjcCompat.m */; };
|
||||
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 +20,8 @@
|
|||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
50C44A1C2150E7800093B3E9 /* FSPagerViewObjcCompat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FSPagerViewObjcCompat.h; sourceTree = "<group>"; };
|
||||
F931E0052158A062001B2A01 /* FSPagerViewObjcCompat.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FSPagerViewObjcCompat.m; 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 +81,8 @@
|
|||
F9580B861E5D9F2B00C5B267 /* FSPageViewLayout.swift */,
|
||||
F9D7BD291E63DD5F003F6A0E /* FSPagerViewLayoutAttributes.swift */,
|
||||
F9580B871E5D9F2B00C5B267 /* FSPageViewTransformer.swift */,
|
||||
50C44A1C2150E7800093B3E9 /* FSPagerViewObjcCompat.h */,
|
||||
F931E0052158A062001B2A01 /* FSPagerViewObjcCompat.m */,
|
||||
);
|
||||
name = Sources;
|
||||
path = ../Sources;
|
||||
|
|
@ -90,6 +96,7 @@
|
|||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
F9580B7B1E5D9F0600C5B267 /* FSPagerView.h in Headers */,
|
||||
50C44A1D2150E7800093B3E9 /* FSPagerViewObjcCompat.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
@ -120,22 +127,24 @@
|
|||
F9580B6D1E5D9F0600C5B267 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0900;
|
||||
LastUpgradeCheck = 1030;
|
||||
ORGANIZATIONNAME = "Wenchao Ding";
|
||||
TargetAttributes = {
|
||||
F9580B751E5D9F0600C5B267 = {
|
||||
CreatedOnToolsVersion = 8.2.1;
|
||||
DevelopmentTeam = HZF422TY46;
|
||||
LastSwiftMigration = 1000;
|
||||
ProvisioningStyle = Automatic;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = F9580B701E5D9F0600C5B267 /* Build configuration list for PBXProject "FSPagerView" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
mainGroup = F9580B6C1E5D9F0600C5B267;
|
||||
productRefGroup = F9580B771E5D9F0600C5B267 /* Products */;
|
||||
|
|
@ -169,6 +178,7 @@
|
|||
F9580B8C1E5D9F2B00C5B267 /* FSPageViewLayout.swift in Sources */,
|
||||
F9580B8A1E5D9F2B00C5B267 /* FSPagerView.swift in Sources */,
|
||||
F9580B8B1E5D9F2B00C5B267 /* FSPagerViewCell.swift in Sources */,
|
||||
F931E0062158A062001B2A01 /* FSPagerViewObjcCompat.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
@ -179,6 +189,7 @@
|
|||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
|
|
@ -188,6 +199,7 @@
|
|||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
|
|
@ -195,6 +207,7 @@
|
|||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
|
|
@ -228,7 +241,7 @@
|
|||
SDKROOT = iphoneos;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 4.0;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
|
|
@ -239,6 +252,7 @@
|
|||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
|
|
@ -248,6 +262,7 @@
|
|||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
|
|
@ -255,6 +270,7 @@
|
|||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
|
|
@ -280,7 +296,7 @@
|
|||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
||||
SWIFT_VERSION = 4.0;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
|
|
@ -291,6 +307,7 @@
|
|||
F9580B7F1E5D9F0600C5B267 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_IDENTITY = "";
|
||||
DEFINES_MODULE = YES;
|
||||
DEVELOPMENT_TEAM = HZF422TY46;
|
||||
|
|
@ -304,13 +321,15 @@
|
|||
PRODUCT_BUNDLE_IDENTIFIER = com.wenchaod.FSPagerView;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_VERSION = 4.0;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
F9580B801E5D9F0600C5B267 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_IDENTITY = "";
|
||||
DEFINES_MODULE = YES;
|
||||
DEVELOPMENT_TEAM = HZF422TY46;
|
||||
|
|
@ -324,7 +343,7 @@
|
|||
PRODUCT_BUNDLE_IDENTIFIER = com.wenchaod.FSPagerView;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_VERSION = 4.0;
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0900"
|
||||
LastUpgradeVersion = "1030"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
|
@ -26,7 +26,6 @@
|
|||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
|
|
@ -37,7 +36,6 @@
|
|||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
language = ""
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.7.2</string>
|
||||
<string>0.8.3</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
F908BC4C1E35AAE4002B2F51 /* 5.jpg in Resources */ = {isa = PBXBuildFile; fileRef = F908BC3D1E35AAE4002B2F51 /* 5.jpg */; };
|
||||
F908BC4D1E35AAE4002B2F51 /* 6.jpg in Resources */ = {isa = PBXBuildFile; fileRef = F908BC3E1E35AAE4002B2F51 /* 6.jpg */; };
|
||||
F908BC4E1E35AAE4002B2F51 /* 7.jpg in Resources */ = {isa = PBXBuildFile; fileRef = F908BC3F1E35AAE4002B2F51 /* 7.jpg */; };
|
||||
F931E00A2158A1E4001B2A01 /* FSPagerViewObjcCompat.m in Sources */ = {isa = PBXBuildFile; fileRef = F931E0092158A1E4001B2A01 /* FSPagerViewObjcCompat.m */; };
|
||||
F93F5E141E319AE8006B7082 /* PageControlExampleViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F93F5E131E319AE8006B7082 /* PageControlExampleViewController.m */; };
|
||||
F9580B641E5D997200C5B267 /* FSPageControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9580B5E1E5D997200C5B267 /* FSPageControl.swift */; };
|
||||
F9580B651E5D997200C5B267 /* FSPagerCollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9580B5F1E5D997200C5B267 /* FSPagerCollectionView.swift */; };
|
||||
|
|
@ -44,6 +45,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>"; };
|
||||
|
|
@ -51,6 +53,7 @@
|
|||
F908BC3D1E35AAE4002B2F51 /* 5.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = 5.jpg; sourceTree = "<group>"; };
|
||||
F908BC3E1E35AAE4002B2F51 /* 6.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = 6.jpg; sourceTree = "<group>"; };
|
||||
F908BC3F1E35AAE4002B2F51 /* 7.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = 7.jpg; sourceTree = "<group>"; };
|
||||
F931E0092158A1E4001B2A01 /* FSPagerViewObjcCompat.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FSPagerViewObjcCompat.m; sourceTree = "<group>"; };
|
||||
F93F5E121E319AE8006B7082 /* PageControlExampleViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PageControlExampleViewController.h; sourceTree = "<group>"; };
|
||||
F93F5E131E319AE8006B7082 /* PageControlExampleViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PageControlExampleViewController.m; sourceTree = "<group>"; };
|
||||
F9580B5E1E5D997200C5B267 /* FSPageControl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FSPageControl.swift; sourceTree = "<group>"; };
|
||||
|
|
@ -121,6 +124,8 @@
|
|||
F9580B621E5D997200C5B267 /* FSPageViewLayout.swift */,
|
||||
F9FF349E1E65B38C001E943F /* FSPagerViewLayoutAttributes.swift */,
|
||||
F9580B631E5D997200C5B267 /* FSPageViewTransformer.swift */,
|
||||
50989DFD2151DB25004DBB4A /* FSPagerViewObjcCompat.h */,
|
||||
F931E0092158A1E4001B2A01 /* FSPagerViewObjcCompat.m */,
|
||||
);
|
||||
name = Sources;
|
||||
path = ../Sources;
|
||||
|
|
@ -251,7 +256,7 @@
|
|||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 0820;
|
||||
LastUpgradeCheck = 0900;
|
||||
LastUpgradeCheck = 1030;
|
||||
ORGANIZATIONNAME = "Wenchao Ding";
|
||||
TargetAttributes = {
|
||||
F9C694481E40C6C1007084B6 = {
|
||||
|
|
@ -271,7 +276,7 @@
|
|||
};
|
||||
buildConfigurationList = F9EC37141E304A830022B6D6 /* Build configuration list for PBXProject "FSPagerViewExample-Objc" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
|
|
@ -341,6 +346,7 @@
|
|||
F93F5E141E319AE8006B7082 /* PageControlExampleViewController.m in Sources */,
|
||||
F9EC371E1E304A830022B6D6 /* main.m in Sources */,
|
||||
F9580B661E5D997200C5B267 /* FSPagerView.swift in Sources */,
|
||||
F931E00A2158A1E4001B2A01 /* FSPagerViewObjcCompat.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
@ -386,8 +392,8 @@
|
|||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = On;
|
||||
SWIFT_VERSION = 4.0;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TEST_TARGET_NAME = "FSPagerViewExample-Objc";
|
||||
};
|
||||
name = Debug;
|
||||
|
|
@ -403,8 +409,8 @@
|
|||
PRODUCT_BUNDLE_IDENTIFIER = "com.wenchaod.FSPagerViewExample-ObjcUITests";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = On;
|
||||
SWIFT_VERSION = 4.0;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TEST_TARGET_NAME = "FSPagerViewExample-Objc";
|
||||
};
|
||||
name = Release;
|
||||
|
|
@ -413,6 +419,7 @@
|
|||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
|
|
@ -422,6 +429,7 @@
|
|||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
|
|
@ -429,6 +437,7 @@
|
|||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
|
|
@ -459,7 +468,7 @@
|
|||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_VERSION = 4.0;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
|
|
@ -468,6 +477,7 @@
|
|||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
|
|
@ -477,6 +487,7 @@
|
|||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
|
|
@ -484,6 +495,7 @@
|
|||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
|
|
@ -508,7 +520,7 @@
|
|||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
||||
SWIFT_VERSION = 4.0;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
|
|
@ -524,7 +536,7 @@
|
|||
PRODUCT_BUNDLE_IDENTIFIER = "com.wenchaod.FSPagerView-Objc";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
|
||||
SWIFT_VERSION = 4.0;
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
|
|
@ -538,7 +550,7 @@
|
|||
PRODUCT_BUNDLE_IDENTIFIER = "com.wenchaod.FSPagerView-Objc";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
|
||||
SWIFT_VERSION = 4.0;
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0830"
|
||||
LastUpgradeVersion = "0940"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
|
|
|||
|
|
@ -8,12 +8,13 @@
|
|||
|
||||
#import "BasicExampleViewController.h"
|
||||
#import "FSPagerViewExample_Objc-Swift.h"
|
||||
|
||||
#import "FSPagerViewObjcCompat.h"
|
||||
|
||||
@interface BasicExampleViewController () <UITableViewDataSource,UITableViewDelegate,FSPagerViewDataSource,FSPagerViewDelegate>
|
||||
|
||||
@property (strong, nonatomic) NSArray<NSString *> *sectionTitles;
|
||||
@property (strong, nonatomic) NSArray<NSString *> *configurationTitles;
|
||||
@property (strong, nonatomic) NSArray<NSString *> *decelerationDistanceOptions;
|
||||
@property (strong, nonatomic) NSArray<NSString *> *imageNames;
|
||||
@property (assign, nonatomic) NSInteger numberOfItems;
|
||||
|
||||
|
|
@ -33,16 +34,18 @@
|
|||
{
|
||||
[super viewDidLoad];
|
||||
|
||||
self.sectionTitles = @[@"Configurations", @"Item Size", @"Interitem Spacing", @"Number Of Items"];
|
||||
self.sectionTitles = @[@"Configurations", @"Deceleration Distance", @"Item Size", @"Interitem Spacing", @"Number Of Items"];
|
||||
self.configurationTitles = @[@"Automatic sliding", @"Infinite"];
|
||||
self.decelerationDistanceOptions = @[@"Automatic", @"1", @"2"];
|
||||
self.imageNames = @[@"1.jpg", @"2.jpg", @"3.jpg", @"4.jpg", @"5.jpg", @"6.jpg", @"7.jpg"];
|
||||
self.numberOfItems = 7;
|
||||
|
||||
[self.pagerView registerClass:[FSPagerViewCell class] forCellWithReuseIdentifier:@"cell"];
|
||||
self.pagerView.itemSize = self.pagerView.frame.size;
|
||||
self.pagerView.itemSize = FSPagerViewAutomaticSize;
|
||||
self.pageControl.numberOfPages = self.imageNames.count;
|
||||
self.pageControl.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight;
|
||||
self.pageControl.contentInsets = UIEdgeInsetsMake(0, 20, 0, 20);
|
||||
|
||||
}
|
||||
|
||||
#pragma mark - UITableViewDataSource
|
||||
|
|
@ -58,8 +61,10 @@
|
|||
case 0:
|
||||
return self.configurationTitles.count;
|
||||
case 1:
|
||||
return self.decelerationDistanceOptions.count;
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
return 1;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -84,32 +89,52 @@
|
|||
return cell;
|
||||
}
|
||||
case 1: {
|
||||
// Decelaration Distance
|
||||
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
|
||||
cell.textLabel.text = self.decelerationDistanceOptions[indexPath.row];
|
||||
switch (indexPath.row) {
|
||||
case 0:
|
||||
// Hardcode like '-1' is bad for readability, but there haven't been a better solution to export a swift constant to objective-c yet.
|
||||
cell.accessoryType = self.pagerView.decelerationDistance == FSPagerViewAutomaticDistance ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
|
||||
break;
|
||||
case 1:
|
||||
cell.accessoryType = self.pagerView.decelerationDistance == 1 ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
|
||||
break;
|
||||
case 2:
|
||||
cell.accessoryType = self.pagerView.decelerationDistance == 2 ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return cell;
|
||||
}
|
||||
case 2: {
|
||||
// Item Spacing
|
||||
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"slider_cell"];
|
||||
UISlider *slider = cell.contentView.subviews.firstObject;
|
||||
slider.tag = indexPath.section;
|
||||
slider.tag = 1;
|
||||
slider.value = ({
|
||||
CGFloat scale = self.pagerView.itemSize.width/self.pagerView.frame.size.width;
|
||||
CGFloat value = (scale-0.5)*2;
|
||||
CGFloat value = (0.5-scale)*2;
|
||||
value;
|
||||
});
|
||||
slider.continuous = YES;
|
||||
return cell;
|
||||
}
|
||||
case 2: {
|
||||
case 3: {
|
||||
// Interitem Spacing
|
||||
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"slider_cell"];
|
||||
UISlider *slider = cell.contentView.subviews.firstObject;
|
||||
slider.tag = indexPath.section;
|
||||
slider.tag = 2;
|
||||
slider.value = self.pagerView.interitemSpacing / 20.0;
|
||||
slider.continuous = YES;
|
||||
return cell;
|
||||
}
|
||||
case 3: {
|
||||
case 4: {
|
||||
// Number Of Items
|
||||
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"slider_cell"];
|
||||
UISlider *slider = cell.contentView.subviews.firstObject;
|
||||
slider.tag = indexPath.section;
|
||||
slider.tag = 3;
|
||||
slider.value = self.numberOfItems / 7.0;
|
||||
slider.minimumValue = 1.0 / 7;
|
||||
slider.maximumValue = 1.0;
|
||||
|
|
@ -126,14 +151,14 @@
|
|||
|
||||
- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
return indexPath.section == 0;
|
||||
return indexPath.section == 0 || indexPath.section == 1;
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
||||
switch (indexPath.section) {
|
||||
case 0:
|
||||
case 0: {
|
||||
if (indexPath.row == 0) {
|
||||
// Automatic Sliding
|
||||
self.pagerView.automaticSlidingInterval = 3.0 - self.pagerView.automaticSlidingInterval;
|
||||
|
|
@ -143,6 +168,24 @@
|
|||
}
|
||||
[tableView reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationAutomatic];
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
switch (indexPath.row) {
|
||||
case 0:
|
||||
self.pagerView.decelerationDistance = FSPagerViewAutomaticDistance;
|
||||
break;
|
||||
case 1:
|
||||
self.pagerView.decelerationDistance = 1;
|
||||
break;
|
||||
case 2:
|
||||
self.pagerView.decelerationDistance = 2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
[tableView reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationAutomatic];
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -181,14 +224,16 @@
|
|||
{
|
||||
[pagerView deselectItemAtIndex:index animated:YES];
|
||||
[pagerView scrollToItemAtIndex:index animated:YES];
|
||||
self.pageControl.currentPage = index;
|
||||
}
|
||||
|
||||
- (void)pagerViewDidScroll:(FSPagerView *)pagerView
|
||||
- (void)pagerViewWillEndDragging:(FSPagerView *)pagerView targetIndex:(NSInteger)targetIndex
|
||||
{
|
||||
if (self.pageControl.currentPage != pagerView.currentIndex) {
|
||||
self.pageControl.currentPage = pagerView.currentIndex;
|
||||
}
|
||||
self.pageControl.currentPage = targetIndex;
|
||||
}
|
||||
|
||||
- (void)pagerViewDidEndScrollAnimation:(FSPagerView *)pagerView
|
||||
{
|
||||
self.pageControl.currentPage = pagerView.currentIndex;
|
||||
}
|
||||
|
||||
#pragma mark - Target actions
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#import "PageControlExampleViewController.h"
|
||||
#import "FSPagerViewExample_Objc-Swift.h"
|
||||
#import "FSPagerViewObjcCompat.h"
|
||||
|
||||
@interface PageControlExampleViewController () <UITableViewDataSource,UITableViewDelegate,FSPagerViewDataSource,FSPagerViewDelegate>
|
||||
|
||||
|
|
@ -48,7 +49,7 @@
|
|||
self.pageControl.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight;
|
||||
self.pageControl.contentInsets = UIEdgeInsetsMake(0, 20, 0, 20);
|
||||
|
||||
self.pagerView.itemSize = CGSizeZero; // Fill parent
|
||||
self.pagerView.itemSize = FSPagerViewAutomaticSize; // Fill parent
|
||||
[self.pagerView registerClass:[FSPagerViewCell class] forCellWithReuseIdentifier:@"cell"];
|
||||
}
|
||||
|
||||
|
|
@ -159,11 +160,9 @@
|
|||
|
||||
#pragma mark - FSPagerViewDelegate
|
||||
|
||||
- (void)pagerViewDidScroll:(FSPagerView *)pagerView
|
||||
- (void)pagerViewWillEndDragging:(FSPagerView *)pagerView targetIndex:(NSInteger)targetIndex
|
||||
{
|
||||
if (self.pageControl.currentPage != pagerView.currentIndex) {
|
||||
self.pageControl.currentPage = pagerView.currentIndex;
|
||||
}
|
||||
self.pageControl.currentPage = targetIndex;
|
||||
}
|
||||
|
||||
#pragma mark - Target actions
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#import "TransformerExampleViewController.h"
|
||||
#import "FSPagerViewExample_Objc-Swift.h"
|
||||
#import "FSPagerViewObjcCompat.h"
|
||||
|
||||
@interface TransformerExampleViewController () <UITableViewDataSource,UITableViewDelegate,FSPagerViewDataSource,FSPagerViewDelegate>
|
||||
|
||||
|
|
@ -148,27 +149,32 @@
|
|||
case FSPagerViewTransformerTypeCrossFading:
|
||||
case FSPagerViewTransformerTypeZoomOut:
|
||||
case FSPagerViewTransformerTypeDepth: {
|
||||
self.pagerView.itemSize = CGSizeZero; // 'Zero' means fill the size of parent
|
||||
self.pagerView.itemSize = FSPagerViewAutomaticSize;
|
||||
self.pagerView.decelerationDistance = 1;
|
||||
break;
|
||||
}
|
||||
case FSPagerViewTransformerTypeLinear:
|
||||
case FSPagerViewTransformerTypeOverlap: {
|
||||
CGAffineTransform transform = CGAffineTransformMakeScale(0.6, 0.75);
|
||||
self.pagerView.itemSize = CGSizeApplyAffineTransform(self.pagerView.frame.size, transform);
|
||||
self.pagerView.decelerationDistance = FSPagerViewAutomaticDistance;
|
||||
break;
|
||||
}
|
||||
case FSPagerViewTransformerTypeFerrisWheel:
|
||||
case FSPagerViewTransformerTypeInvertedFerrisWheel: {
|
||||
self.pagerView.itemSize = CGSizeMake(180, 140);
|
||||
self.pagerView.decelerationDistance = FSPagerViewAutomaticDistance;
|
||||
break;
|
||||
}
|
||||
case FSPagerViewTransformerTypeCoverFlow: {
|
||||
self.pagerView.itemSize = CGSizeMake(220, 170);
|
||||
self.pagerView.decelerationDistance = FSPagerViewAutomaticDistance;
|
||||
break;
|
||||
}
|
||||
case FSPagerViewTransformerTypeCubic: {
|
||||
CGAffineTransform transform = CGAffineTransformMakeScale(0.9, 0.9);
|
||||
self.pagerView.itemSize = CGSizeApplyAffineTransform(self.pagerView.frame.size, transform);
|
||||
self.pagerView.decelerationDistance = 1;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
//
|
||||
// Package.swift
|
||||
// FSPagerView
|
||||
|
|
@ -24,12 +25,17 @@
|
|||
// THE SOFTWARE.
|
||||
|
||||
|
||||
import Foundation
|
||||
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "FSPagerView",
|
||||
dependencies : [],
|
||||
exclude: []
|
||||
platforms: [
|
||||
.iOS(.v9)
|
||||
],
|
||||
products: [
|
||||
.library(name: "FSPagerView", targets: ["FSPagerView"]),
|
||||
],
|
||||
targets: [
|
||||
.target(name: "FSPagerView", path: "Sources", exclude: ["FSPagerViewObjcCompat.h", "FSPagerViewObjcCompat.m"]),
|
||||
]
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||

|
||||
|
||||
[](#) <br/>
|
||||
[](#) <br/>
|
||||
[](http://cocoadocs.org/docsets/FSPagerView)
|
||||
[](http://cocoadocs.org/docsets/FSPagerView)
|
||||
[](https://github.com/Carthage/Carthage)
|
||||
|
|
@ -46,8 +46,17 @@ A boolean value indicates whether the pager view has infinite number of items. D
|
|||
pagerView.isInfinite = YES;
|
||||
```
|
||||
|
||||
### decelerationDistance
|
||||
An unsigned integer value that determines the paging distance of the pager view, which indicates the number of passing items during the deceleration. When the value of this property is FSPagerViewAutomaticDistance, the actual 'distance' is automatically calculated according to the scrolling speed of the pager view. Default is 1.
|
||||
|
||||
**e.g.**
|
||||
|
||||
```objc
|
||||
pagerView.decelerationDistance = 2
|
||||
```
|
||||
|
||||
### itemSize
|
||||
The item size of the pager view. .zero means always fill the bounds of the pager view. Default is .zero.
|
||||
The item size of the pager view. When the value of this property is FSPagerViewAutomaticSize, the items fill the entire visible area of the pager view. Default is FSPagerViewAutomaticSize.
|
||||
|
||||
|
||||
**e.g.**
|
||||
|
|
@ -149,7 +158,7 @@ pagerView.transformer = [[FSPagerViewTransformer alloc] initWithType:FSPagerView
|
|||
|Cubic|
|
||||
|------|
|
||||
|  |
|
||||
```swift
|
||||
```objc
|
||||
pagerView.transformer = [[FSPagerViewTransformer alloc] initWithType:FSPagerViewTransformerTypeCubic];
|
||||
```
|
||||
---
|
||||
|
|
@ -185,7 +194,8 @@ pageControl.currentPage = 1;
|
|||
The horizontal alignment of content within the control’s bounds. Default is center.
|
||||
|
||||
**e.g.**
|
||||
```swift
|
||||
|
||||
```objc
|
||||
pageControl.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight;
|
||||
```
|
||||
|
||||
|
|
@ -280,8 +290,10 @@ FSPageControl *pageControl = [[FSPageControl alloc] initWithFrame:frame2];
|
|||
3、Register a cell class.
|
||||
|
||||
```objc
|
||||
- (void)viewDidLoad {
|
||||
[self.pagerView registerClass:[FSPagerViewCell class] forCellWithReuseIdentifier:@"cell"];
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
[self.pagerView registerClass:[FSPagerViewCell class] forCellWithReuseIdentifier:@"cell"];
|
||||
}
|
||||
```
|
||||
|
||||
|
|
@ -388,12 +400,11 @@ FSPageControl *pageControl = [[FSPageControl alloc] initWithFrame:frame2];
|
|||
* Buy me a ***Coffee***. ☕️
|
||||
|
||||
<a href="https://www.paypal.me/WenchaoD" target="_blank"><img src="https://www.paypalobjects.com/webstatic/i/logo/rebrand/ppcom.svg" width="100" height="40" style="margin-bottom:-15px;"></a> |
|
||||
<a href="https://cloud.githubusercontent.com/assets/5186464/15096775/bacc0506-1539-11e6-91b7-b1a7a773622b.png" target="_blank"><img src="http://a1.mzstatic.com/us/r30/Purple49/v4/50/16/b3/5016b341-39c1-b47b-2994-d7e23823baed/icon175x175.png" width="40" height="40" style="margin-bottom:-15px;-webkit-border-radius:10px;border:1px solid rgba(30, 154, 236, 1);"></a> |
|
||||
<a href="https://user-images.githubusercontent.com/5186464/45949944-46960480-c030-11e8-9e90-30b015698cf6.png" target="_blank"><img src="http://a1.mzstatic.com/us/r30/Purple49/v4/50/16/b3/5016b341-39c1-b47b-2994-d7e23823baed/icon175x175.png" width="40" height="40" style="margin-bottom:-15px;-webkit-border-radius:10px;border:1px solid rgba(30, 154, 236, 1);"></a> |
|
||||
<a href="https://cloud.githubusercontent.com/assets/5186464/15096872/b06f3a3a-153c-11e6-89f9-2e9c7b88ef42.png" target="_blank"><img src="http://a4.mzstatic.com/us/r30/Purple49/v4/23/31/14/233114f8-2e8d-7b63-8dc5-85d29893061e/icon175x175.jpeg" height="40" width="40" style="margin-bottom:-15px; -webkit-border-radius: 10px;border:1px solid rgba(43, 177, 0, 1)"></a>
|
||||
|
||||
---
|
||||
|
||||
ˉ
|
||||
## Author
|
||||
* ***微博:[@WenchaoD](http://weibo.com/WenchaoD)***
|
||||
* ***Twitter: [@WenchaoD](https://twitter.com/WenchaoD)***
|
||||
|
|
|
|||
22
README.md
22
README.md
|
|
@ -1,6 +1,6 @@
|
|||

|
||||
|
||||
[](#) <br/>
|
||||
[](#) <br/>
|
||||
[](http://cocoadocs.org/docsets/FSPagerView)
|
||||
[](http://cocoadocs.org/docsets/FSPagerView)
|
||||
[](https://github.com/Carthage/Carthage)
|
||||
|
|
@ -51,9 +51,17 @@ A boolean value indicates whether the pager view has infinite number of items. D
|
|||
pagerView.isInfinite = true
|
||||
```
|
||||
|
||||
### itemSize
|
||||
The item size of the pager view. .zero means always fill the bounds of the pager view. Default is .zero.
|
||||
### decelerationDistance
|
||||
An unsigned integer value that determines the paging distance of the pager view, which indicates the number of passing items during the deceleration. When the value of this property is FSPagerView.automaticDistance, the actual 'distance' is automatically calculated according to the scrolling speed of the pager view. Default is 1.
|
||||
|
||||
**e.g.**
|
||||
|
||||
```swift
|
||||
pagerView.decelerationDistance = 2
|
||||
```
|
||||
|
||||
### itemSize
|
||||
The item size of the pager view. When the value of this property is FSPagerView.automaticSize, the items fill the entire visible area of the pager view. Default is FSPagerView.automaticSize.
|
||||
|
||||
**e.g.**
|
||||
|
||||
|
|
@ -77,7 +85,7 @@ pagerView.interitemSpacing = 10
|
|||
|  |
|
||||
|
||||
```swift
|
||||
pagerView.transformer = FSPagerViewTransformer(type: .crossfading)
|
||||
pagerView.transformer = FSPagerViewTransformer(type: .crossFading)
|
||||
```
|
||||
---
|
||||
|
||||
|
|
@ -88,7 +96,7 @@ pagerView.transformer = FSPagerViewTransformer(type: .crossfading)
|
|||
|  |
|
||||
|
||||
```swift
|
||||
pagerView.transformer = FSPagerViewTransformer(type: .zoomout)
|
||||
pagerView.transformer = FSPagerViewTransformer(type: .zoomOut)
|
||||
```
|
||||
---
|
||||
|
||||
|
|
@ -395,7 +403,7 @@ func pagerViewDidEndDecelerating(_ pagerView: FSPagerView)
|
|||
* Buy me a Coffee. ☕️
|
||||
|
||||
<a href="https://www.paypal.me/WenchaoD" target="_blank"><img src="https://www.paypalobjects.com/webstatic/i/logo/rebrand/ppcom.svg" width="100" height="40" style="margin-bottom:-15px;"></a> |
|
||||
<a href="https://cloud.githubusercontent.com/assets/5186464/15096775/bacc0506-1539-11e6-91b7-b1a7a773622b.png" target="_blank"><img src="http://a1.mzstatic.com/us/r30/Purple49/v4/50/16/b3/5016b341-39c1-b47b-2994-d7e23823baed/icon175x175.png" width="40" height="40" style="margin-bottom:-15px;-webkit-border-radius:10px;border:1px solid rgba(30, 154, 236, 1);"></a> |
|
||||
<a href="https://user-images.githubusercontent.com/5186464/45949944-46960480-c030-11e8-9e90-30b015698cf6.png" target="_blank"><img src="http://a1.mzstatic.com/us/r30/Purple49/v4/50/16/b3/5016b341-39c1-b47b-2994-d7e23823baed/icon175x175.png" width="40" height="40" style="margin-bottom:-15px;-webkit-border-radius:10px;border:1px solid rgba(30, 154, 236, 1);"></a> |
|
||||
<a href="https://cloud.githubusercontent.com/assets/5186464/15096872/b06f3a3a-153c-11e6-89f9-2e9c7b88ef42.png" target="_blank"><img src="http://a4.mzstatic.com/us/r30/Purple49/v4/23/31/14/233114f8-2e8d-7b63-8dc5-85d29893061e/icon175x175.jpeg" height="40" width="40" style="margin-bottom:-15px; -webkit-border-radius: 10px;border:1px solid rgba(43, 177, 0, 1)"></a>
|
||||
|
||||
---
|
||||
|
|
@ -409,4 +417,4 @@ func pagerViewDidEndDecelerating(_ pagerView: FSPagerView)
|
|||
|
||||
---
|
||||
|
||||
# [Documentation](http://cocoadocs.org/docsets/FSPagerView)
|
||||
# [Documentation](http://cocoadocs.org/docsets/FSPagerView)
|
||||
|
|
|
|||
|
|
@ -101,6 +101,12 @@
|
|||
"idiom" : "ipad",
|
||||
"filename" : "Icon-167.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "1024x1024",
|
||||
"idiom" : "ios-marketing",
|
||||
"filename" : "icon-1024.png",
|
||||
"scale" : "1x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 51 KiB |
|
|
@ -8,11 +8,9 @@
|
|||
|
||||
import UIKit
|
||||
|
||||
@IBDesignable
|
||||
open class FSPageControl: UIControl {
|
||||
|
||||
/// The number of page indicators of the page control. Default is 0.
|
||||
@IBInspectable
|
||||
open var numberOfPages: Int = 0 {
|
||||
didSet {
|
||||
self.setNeedsCreateIndicators()
|
||||
|
|
@ -20,7 +18,6 @@ open class FSPageControl: UIControl {
|
|||
}
|
||||
|
||||
/// The current page, highlighted by the page control. Default is 0.
|
||||
@IBInspectable
|
||||
open var currentPage: Int = 0 {
|
||||
didSet {
|
||||
self.setNeedsUpdateIndicators()
|
||||
|
|
@ -28,7 +25,6 @@ open class FSPageControl: UIControl {
|
|||
}
|
||||
|
||||
/// The spacing to use of page indicators in the page control.
|
||||
@IBInspectable
|
||||
open var itemSpacing: CGFloat = 6 {
|
||||
didSet {
|
||||
self.setNeedsUpdateIndicators()
|
||||
|
|
@ -36,7 +32,6 @@ open class FSPageControl: UIControl {
|
|||
}
|
||||
|
||||
/// The spacing to use between page indicators in the page control.
|
||||
@IBInspectable
|
||||
open var interitemSpacing: CGFloat = 6 {
|
||||
didSet {
|
||||
self.setNeedsLayout()
|
||||
|
|
@ -44,7 +39,6 @@ open class FSPageControl: UIControl {
|
|||
}
|
||||
|
||||
/// The distance that the page indicators is inset from the enclosing page control.
|
||||
@IBInspectable
|
||||
open var contentInsets: UIEdgeInsets = .zero {
|
||||
didSet {
|
||||
self.setNeedsLayout()
|
||||
|
|
@ -52,26 +46,25 @@ open class FSPageControl: UIControl {
|
|||
}
|
||||
|
||||
/// The horizontal alignment of content within the control’s bounds. Default is center.
|
||||
open override var contentHorizontalAlignment: UIControlContentHorizontalAlignment {
|
||||
open override var contentHorizontalAlignment: UIControl.ContentHorizontalAlignment {
|
||||
didSet {
|
||||
self.setNeedsLayout()
|
||||
}
|
||||
}
|
||||
|
||||
/// Hide the indicator if there is only one page. default is NO
|
||||
@IBInspectable
|
||||
open var hidesForSinglePage: Bool = false {
|
||||
didSet {
|
||||
self.setNeedsUpdateIndicators()
|
||||
}
|
||||
}
|
||||
|
||||
internal var strokeColors: [UIControlState: UIColor] = [:]
|
||||
internal var fillColors: [UIControlState: UIColor] = [:]
|
||||
internal var paths: [UIControlState: UIBezierPath] = [:]
|
||||
internal var images: [UIControlState: UIImage] = [:]
|
||||
internal var alphas: [UIControlState: CGFloat] = [:]
|
||||
internal var transforms: [UIControlState: CGAffineTransform] = [:]
|
||||
internal var strokeColors: [UIControl.State: UIColor] = [:]
|
||||
internal var fillColors: [UIControl.State: UIColor] = [:]
|
||||
internal var paths: [UIControl.State: UIBezierPath] = [:]
|
||||
internal var images: [UIControl.State: UIImage] = [:]
|
||||
internal var alphas: [UIControl.State: CGFloat] = [:]
|
||||
internal var transforms: [UIControl.State: CGAffineTransform] = [:]
|
||||
|
||||
fileprivate weak var contentView: UIView!
|
||||
|
||||
|
|
@ -117,10 +110,12 @@ open class FSPageControl: UIControl {
|
|||
case .right, .trailing:
|
||||
let contentWidth = diameter*CGFloat(self.numberOfPages) + CGFloat(self.numberOfPages-1)*spacing
|
||||
return contentView.frame.width - contentWidth
|
||||
default:
|
||||
return 0
|
||||
}
|
||||
}()
|
||||
for (index,value) in self.indicatorLayers.enumerated() {
|
||||
let state: UIControlState = (index == self.currentPage) ? .selected : .normal
|
||||
let state: UIControl.State = (index == self.currentPage) ? .selected : .normal
|
||||
let image = self.images[state]
|
||||
let size = image?.size ?? CGSize(width: diameter, height: diameter)
|
||||
let origin = CGPoint(x: x - (size.width-diameter)*0.5, y: self.contentView.bounds.midY-size.height*0.5)
|
||||
|
|
@ -136,7 +131,7 @@ open class FSPageControl: UIControl {
|
|||
/// - strokeColor: The stroke color to use for the specified state.
|
||||
/// - state: The state that uses the specified stroke color.
|
||||
@objc(setStrokeColor:forState:)
|
||||
open func setStrokeColor(_ strokeColor: UIColor?, for state: UIControlState) {
|
||||
open func setStrokeColor(_ strokeColor: UIColor?, for state: UIControl.State) {
|
||||
guard self.strokeColors[state] != strokeColor else {
|
||||
return
|
||||
}
|
||||
|
|
@ -150,7 +145,7 @@ open class FSPageControl: UIControl {
|
|||
/// - fillColor: The fill color to use for the specified state.
|
||||
/// - state: The state that uses the specified fill color.
|
||||
@objc(setFillColor:forState:)
|
||||
open func setFillColor(_ fillColor: UIColor?, for state: UIControlState) {
|
||||
open func setFillColor(_ fillColor: UIColor?, for state: UIControl.State) {
|
||||
guard self.fillColors[state] != fillColor else {
|
||||
return
|
||||
}
|
||||
|
|
@ -164,7 +159,7 @@ open class FSPageControl: UIControl {
|
|||
/// - image: The image to use for the specified state.
|
||||
/// - state: The state that uses the specified image.
|
||||
@objc(setImage:forState:)
|
||||
open func setImage(_ image: UIImage?, for state: UIControlState) {
|
||||
open func setImage(_ image: UIImage?, for state: UIControl.State) {
|
||||
guard self.images[state] != image else {
|
||||
return
|
||||
}
|
||||
|
|
@ -179,7 +174,7 @@ open class FSPageControl: UIControl {
|
|||
/// - Parameters:
|
||||
/// - alpha: The alpha value to use for the specified state.
|
||||
/// - state: The state that uses the specified alpha.
|
||||
open func setAlpha(_ alpha: CGFloat, for state: UIControlState) {
|
||||
open func setAlpha(_ alpha: CGFloat, for state: UIControl.State) {
|
||||
guard self.alphas[state] != alpha else {
|
||||
return
|
||||
}
|
||||
|
|
@ -193,7 +188,7 @@ open class FSPageControl: UIControl {
|
|||
/// - path: The path to use for the specified state.
|
||||
/// - state: The state that uses the specified path.
|
||||
@objc(setPath:forState:)
|
||||
open func setPath(_ path: UIBezierPath?, for state: UIControlState) {
|
||||
open func setPath(_ path: UIBezierPath?, for state: UIControl.State) {
|
||||
guard self.paths[state] != path else {
|
||||
return
|
||||
}
|
||||
|
|
@ -240,8 +235,8 @@ open class FSPageControl: UIControl {
|
|||
}
|
||||
|
||||
fileprivate func updateIndicatorAttributes(for layer: CAShapeLayer) {
|
||||
let index = self.indicatorLayers.index(of: layer)
|
||||
let state: UIControlState = index == self.currentPage ? .selected : .normal
|
||||
let index = self.indicatorLayers.firstIndex(of: layer)
|
||||
let state: UIControl.State = index == self.currentPage ? .selected : .normal
|
||||
if let image = self.images[state] {
|
||||
layer.strokeColor = nil
|
||||
layer.fillColor = nil
|
||||
|
|
@ -300,7 +295,7 @@ open class FSPageControl: UIControl {
|
|||
|
||||
}
|
||||
|
||||
extension UIControlState: Hashable {
|
||||
extension UIControl.State: Hashable {
|
||||
public var hashValue: Int {
|
||||
return Int((6777*self.rawValue+3777)%UInt(UInt16.max))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,19 +14,16 @@ class FSPagerViewLayout: UICollectionViewLayout {
|
|||
internal var leadingSpacing: CGFloat = 0
|
||||
internal var itemSpacing: CGFloat = 0
|
||||
internal var needsReprepare = true
|
||||
internal var scrollDirection: FSPagerViewScrollDirection = .horizontal
|
||||
internal var scrollDirection: FSPagerView.ScrollDirection = .horizontal
|
||||
|
||||
open override class var layoutAttributesClass: AnyClass {
|
||||
get {
|
||||
return FSPagerViewLayoutAttributes.self
|
||||
}
|
||||
return FSPagerViewLayoutAttributes.self
|
||||
}
|
||||
|
||||
fileprivate var pagerView: FSPagerView? {
|
||||
return self.collectionView?.superview?.superview as? FSPagerView
|
||||
}
|
||||
|
||||
fileprivate var isInfinite: Bool = true
|
||||
fileprivate var collectionViewSize: CGSize = .zero
|
||||
fileprivate var numberOfSections = 1
|
||||
fileprivate var numberOfItems = 0
|
||||
|
|
@ -45,7 +42,7 @@ class FSPagerViewLayout: UICollectionViewLayout {
|
|||
|
||||
deinit {
|
||||
#if !os(tvOS)
|
||||
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
|
||||
NotificationCenter.default.removeObserver(self, name: UIDevice.orientationDidChangeNotification, object: nil)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -129,7 +126,7 @@ class FSPagerViewLayout: UICollectionViewLayout {
|
|||
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)
|
||||
// https://stackoverflow.com/a/10335601/2398107
|
||||
while origin-maxPosition <= max(CGFloat(100.0) * .ulpOfOne * fabs(origin+maxPosition), .leastNonzeroMagnitude) {
|
||||
while origin-maxPosition <= max(CGFloat(100.0) * .ulpOfOne * abs(origin+maxPosition), .leastNonzeroMagnitude) {
|
||||
let indexPath = IndexPath(item: itemIndex%self.numberOfItems, section: itemIndex/self.numberOfItems)
|
||||
let attributes = self.layoutAttributesForItem(at: indexPath) as! FSPagerViewLayoutAttributes
|
||||
self.applyTransform(to: attributes, with: self.pagerView?.transformer)
|
||||
|
|
@ -143,6 +140,7 @@ class FSPagerViewLayout: UICollectionViewLayout {
|
|||
|
||||
override open func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
|
||||
let attributes = FSPagerViewLayoutAttributes(forCellWith: indexPath)
|
||||
attributes.indexPath = indexPath
|
||||
let frame = self.frame(for: indexPath)
|
||||
let center = CGPoint(x: frame.midX, y: frame.midY)
|
||||
attributes.center = center
|
||||
|
|
@ -151,39 +149,48 @@ 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
|
||||
|
||||
func calculateTargetOffset(by proposedOffset: CGFloat, boundedOffset: CGFloat) -> CGFloat {
|
||||
var targetOffset: CGFloat
|
||||
if pagerView.decelerationDistance == FSPagerView.automaticDistance {
|
||||
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.decelerationDistance-1, 0)
|
||||
switch velocity.x {
|
||||
case 0.3 ... CGFloat.greatestFiniteMagnitude:
|
||||
targetOffset = ceil(collectionView.contentOffset.x/self.itemSpacing+CGFloat(extraDistance)) * self.itemSpacing
|
||||
case -CGFloat.greatestFiniteMagnitude ... -0.3:
|
||||
targetOffset = floor(collectionView.contentOffset.x/self.itemSpacing-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, 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, boundedOffset: boundedOffset)
|
||||
}()
|
||||
proposedContentOffset = CGPoint(x: proposedContentOffsetX, y: proposedContentOffsetY)
|
||||
return proposedContentOffset
|
||||
|
|
@ -250,7 +257,7 @@ class FSPagerViewLayout: UICollectionViewLayout {
|
|||
|
||||
fileprivate func commonInit() {
|
||||
#if !os(tvOS)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(didReceiveNotification(notification:)), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(didReceiveNotification(notification:)), name: UIDevice.orientationDidChangeNotification, object: nil)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -258,12 +265,11 @@ class FSPagerViewLayout: UICollectionViewLayout {
|
|||
guard let collectionView = self.collectionView, let pagerView = self.pagerView else {
|
||||
return
|
||||
}
|
||||
let currentIndex = max(0, min(pagerView.currentIndex, pagerView.numberOfItems - 1))
|
||||
let newIndexPath = IndexPath(item: currentIndex, section: self.isInfinite ? self.numberOfSections/2 : 0)
|
||||
let currentIndex = pagerView.currentIndex
|
||||
let newIndexPath = IndexPath(item: currentIndex, section: pagerView.isInfinite ? self.numberOfSections/2 : 0)
|
||||
let contentOffset = self.contentOffset(for: newIndexPath)
|
||||
let newBounds = CGRect(origin: contentOffset, size: collectionView.frame.size)
|
||||
collectionView.bounds = newBounds
|
||||
pagerView.currentIndex = currentIndex;
|
||||
}
|
||||
|
||||
fileprivate func applyTransform(to attributes: FSPagerViewLayoutAttributes, with transformer: FSPagerViewTransformer?) {
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@ open class FSPagerViewTransformer: NSObject {
|
|||
open internal(set) weak var pagerView: FSPagerView?
|
||||
open internal(set) var type: FSPagerViewTransformerType
|
||||
|
||||
open var minimumScale: CGFloat = 0.65
|
||||
open var minimumAlpha: CGFloat = 0.6
|
||||
@objc open var minimumScale: CGFloat = 0.65
|
||||
@objc open var minimumAlpha: CGFloat = 0.6
|
||||
|
||||
@objc
|
||||
public init(type: FSPagerViewTransformerType) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// FSPagerViewCollectionView.swift
|
||||
// FSPagerCollectionView.swift
|
||||
// FSPagerView
|
||||
//
|
||||
// Created by Wenchao Ding on 24/12/2016.
|
||||
|
|
@ -10,11 +10,7 @@
|
|||
|
||||
import UIKit
|
||||
|
||||
class FSPagerViewCollectionView: UICollectionView {
|
||||
|
||||
fileprivate var pagerView: FSPagerView? {
|
||||
return self.superview?.superview as? FSPagerView
|
||||
}
|
||||
class FSPagerCollectionView: UICollectionView {
|
||||
|
||||
#if !os(tvOS)
|
||||
override var scrollsToTop: Bool {
|
||||
|
|
@ -52,7 +48,7 @@ class FSPagerViewCollectionView: UICollectionView {
|
|||
|
||||
fileprivate func commonInit() {
|
||||
self.contentInset = .zero
|
||||
self.decelerationRate = UIScrollViewDecelerationRateFast
|
||||
self.decelerationRate = UIScrollView.DecelerationRate.fast
|
||||
self.showsVerticalScrollIndicator = false
|
||||
self.showsHorizontalScrollIndicator = false
|
||||
if #available(iOS 10.0, *) {
|
||||
|
|
|
|||
|
|
@ -74,29 +74,25 @@ public protocol FSPagerViewDelegate: NSObjectProtocol {
|
|||
|
||||
}
|
||||
|
||||
@objc
|
||||
public enum FSPagerViewScrollDirection: Int {
|
||||
case horizontal
|
||||
case vertical
|
||||
}
|
||||
|
||||
@IBDesignable
|
||||
open class FSPagerView: UIView,UICollectionViewDataSource,UICollectionViewDelegate {
|
||||
|
||||
// MARK: - Public properties
|
||||
|
||||
/// The object that acts as the data source of the pager view.
|
||||
@IBOutlet open weak var dataSource: FSPagerViewDataSource?
|
||||
|
||||
/// The object that acts as the delegate of the pager view.
|
||||
@IBOutlet open weak var delegate: FSPagerViewDelegate?
|
||||
|
||||
/// The scroll direction of the pager view. Default is horizontal.
|
||||
open var scrollDirection: FSPagerViewScrollDirection = .horizontal {
|
||||
@objc
|
||||
open var scrollDirection: FSPagerView.ScrollDirection = .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 {
|
||||
didSet {
|
||||
self.cancelTimer()
|
||||
|
|
@ -107,23 +103,20 @@ open class FSPagerView: UIView,UICollectionViewDataSource,UICollectionViewDelega
|
|||
}
|
||||
|
||||
/// The spacing to use between items in the pager view. Default is 0.
|
||||
@IBInspectable
|
||||
open var interitemSpacing: CGFloat = 0 {
|
||||
didSet {
|
||||
self.collectionViewLayout.forceInvalidate()
|
||||
}
|
||||
}
|
||||
|
||||
/// The item size of the pager view. .zero means always fill the bounds of the pager view. Default is .zero.
|
||||
@IBInspectable
|
||||
open var itemSize: CGSize = .zero {
|
||||
/// The item size of the pager view. When the value of this property is FSPagerView.automaticSize, the items fill the entire visible area of the pager view. Default is FSPagerView.automaticSize.
|
||||
open var itemSize: CGSize = automaticSize {
|
||||
didSet {
|
||||
self.collectionViewLayout.forceInvalidate()
|
||||
}
|
||||
}
|
||||
|
||||
/// A Boolean value indicates that whether the pager view has infinite items. Default is false.
|
||||
@IBInspectable
|
||||
open var isInfinite: Bool = false {
|
||||
didSet {
|
||||
self.collectionViewLayout.needsReprepare = true
|
||||
|
|
@ -131,24 +124,41 @@ open class FSPagerView: UIView,UICollectionViewDataSource,UICollectionViewDelega
|
|||
}
|
||||
}
|
||||
|
||||
/// An unsigned integer value that determines the deceleration distance of the pager view, which indicates the number of passing items during the deceleration. When the value of this property is FSPagerView.automaticDistance, the actual 'distance' is automatically calculated according to the scrolling speed of the pager view. Default is 1.
|
||||
open var decelerationDistance: UInt = 1
|
||||
|
||||
/// A Boolean value that determines whether scrolling is enabled.
|
||||
open var isScrollEnabled: Bool {
|
||||
set { self.collectionView.isScrollEnabled = newValue }
|
||||
get { return self.collectionView.isScrollEnabled }
|
||||
}
|
||||
|
||||
/// A Boolean value that controls whether the pager view bounces past the edge of content and back again.
|
||||
open var bounces: Bool {
|
||||
set { self.collectionView.bounces = newValue }
|
||||
get { return self.collectionView.bounces }
|
||||
}
|
||||
|
||||
/// A Boolean value that determines whether bouncing always occurs when horizontal scrolling reaches the end of the content view.
|
||||
@IBInspectable
|
||||
open var alwaysBounceHorizontal: Bool = false {
|
||||
didSet {
|
||||
self.collectionView.alwaysBounceHorizontal = self.alwaysBounceHorizontal;
|
||||
}
|
||||
open var alwaysBounceHorizontal: Bool {
|
||||
set { self.collectionView.alwaysBounceHorizontal = newValue }
|
||||
get { return self.collectionView.alwaysBounceHorizontal }
|
||||
}
|
||||
|
||||
/// A Boolean value that determines whether bouncing always occurs when vertical scrolling reaches the end of the content view.
|
||||
@IBInspectable
|
||||
open var alwaysBounceVertical: Bool = false {
|
||||
open var alwaysBounceVertical: Bool {
|
||||
set { self.collectionView.alwaysBounceVertical = newValue }
|
||||
get { return self.collectionView.alwaysBounceVertical }
|
||||
}
|
||||
|
||||
/// A Boolean value that controls whether the infinite loop is removed if there is only one item. Default is false.
|
||||
open var removesInfiniteLoopForSingleItem: Bool = false {
|
||||
didSet {
|
||||
self.collectionView.alwaysBounceVertical = self.alwaysBounceVertical;
|
||||
self.reloadData()
|
||||
}
|
||||
}
|
||||
|
||||
/// The background view of the pager view.
|
||||
@IBInspectable
|
||||
open var backgroundView: UIView? {
|
||||
didSet {
|
||||
if let backgroundView = self.backgroundView {
|
||||
|
|
@ -173,38 +183,32 @@ open class FSPagerView: UIView,UICollectionViewDataSource,UICollectionViewDelega
|
|||
// MARK: - Public readonly-properties
|
||||
|
||||
/// Returns whether the user has touched the content to initiate scrolling.
|
||||
@objc
|
||||
open var isTracking: Bool {
|
||||
return self.collectionView.isTracking
|
||||
}
|
||||
|
||||
/// Remove the infinite loop if there is only one item. default is NO
|
||||
@IBInspectable
|
||||
open var removesInfiniteLoopForSingleItem: Bool = false {
|
||||
didSet {
|
||||
self.reloadData()
|
||||
}
|
||||
}
|
||||
|
||||
/// The percentage of x position at which the origin of the content view is offset from the origin of the pagerView view.
|
||||
@objc
|
||||
open var scrollOffset: CGFloat {
|
||||
let contentOffset = max(self.collectionView.contentOffset.x, self.collectionView.contentOffset.y)
|
||||
let scrollOffset = Double(contentOffset/self.collectionViewLayout.itemSpacing)
|
||||
return fmod(CGFloat(scrollOffset), CGFloat(Double(self.numberOfItems)))
|
||||
return fmod(CGFloat(scrollOffset), CGFloat(self.numberOfItems))
|
||||
}
|
||||
|
||||
/// The underlying gesture recognizer for pan gestures.
|
||||
@objc
|
||||
open var panGestureRecognizer: UIPanGestureRecognizer {
|
||||
return self.collectionView.panGestureRecognizer
|
||||
}
|
||||
|
||||
@objc open internal(set) dynamic var currentIndex: Int = 0
|
||||
@objc open fileprivate(set) dynamic var currentIndex: Int = 0
|
||||
|
||||
// MARK: - Private properties
|
||||
|
||||
internal weak var collectionViewLayout: FSPagerViewLayout!
|
||||
internal weak var collectionView: FSPagerViewCollectionView!
|
||||
internal weak var collectionView: FSPagerCollectionView!
|
||||
internal weak var contentView: UIView!
|
||||
|
||||
internal var timer: Timer?
|
||||
internal var numberOfItems: Int = 0
|
||||
internal var numberOfSections: Int = 0
|
||||
|
|
@ -236,10 +240,15 @@ open class FSPagerView: UIView,UICollectionViewDataSource,UICollectionViewDelega
|
|||
}
|
||||
return IndexPath(item: 0, section: 0)
|
||||
}
|
||||
|
||||
fileprivate var isPossiblyRotating: Bool {
|
||||
guard let animationKeys = self.contentView.layer.animationKeys() else {
|
||||
return false
|
||||
}
|
||||
let rotationAnimationKeys = ["position", "bounds.origin", "bounds.size"]
|
||||
return animationKeys.contains(where: { rotationAnimationKeys.contains($0) })
|
||||
}
|
||||
fileprivate var possibleTargetingIndexPath: IndexPath?
|
||||
|
||||
|
||||
// MARK: - Overriden functions
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
|
|
@ -268,11 +277,14 @@ open class FSPagerView: UIView,UICollectionViewDataSource,UICollectionViewDelega
|
|||
}
|
||||
}
|
||||
|
||||
#if TARGET_INTERFACE_BUILDER
|
||||
|
||||
open override func prepareForInterfaceBuilder() {
|
||||
super.prepareForInterfaceBuilder()
|
||||
self.contentView.layer.borderWidth = 1
|
||||
self.contentView.layer.cornerRadius = 5
|
||||
self.contentView.layer.masksToBounds = true
|
||||
self.contentView.frame = self.bounds
|
||||
let label = UILabel(frame: self.contentView.bounds)
|
||||
label.textAlignment = .center
|
||||
label.font = UIFont.boldSystemFont(ofSize: 25)
|
||||
|
|
@ -280,11 +292,13 @@ open class FSPagerView: UIView,UICollectionViewDataSource,UICollectionViewDelega
|
|||
self.contentView.addSubview(label)
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
deinit {
|
||||
self.collectionView.dataSource = nil
|
||||
self.collectionView.delegate = nil
|
||||
}
|
||||
|
||||
|
||||
// MARK: - UICollectionViewDataSource
|
||||
|
||||
public func numberOfSections(in collectionView: UICollectionView) -> Int {
|
||||
|
|
@ -365,7 +379,7 @@ open class FSPagerView: UIView,UICollectionViewDataSource,UICollectionViewDelega
|
|||
}
|
||||
|
||||
public func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
||||
if self.numberOfItems > 0 {
|
||||
if !self.isPossiblyRotating && self.numberOfItems > 0 {
|
||||
// In case someone is using KVO
|
||||
let currentIndex = lround(Double(self.scrollOffset)) % self.numberOfItems
|
||||
if (currentIndex != self.currentIndex) {
|
||||
|
|
@ -463,7 +477,7 @@ open class FSPagerView: UIView,UICollectionViewDataSource,UICollectionViewDelega
|
|||
@objc(selectItemAtIndex:animated:)
|
||||
open func selectItem(at index: Int, animated: Bool) {
|
||||
let indexPath = self.nearbyIndexPath(for: index)
|
||||
let scrollPosition: UICollectionViewScrollPosition = self.scrollDirection == .horizontal ? .centeredHorizontally : .centeredVertically
|
||||
let scrollPosition: UICollectionView.ScrollPosition = self.scrollDirection == .horizontal ? .centeredHorizontally : .centeredVertically
|
||||
self.collectionView.selectItem(at: indexPath, animated: animated, scrollPosition: scrollPosition)
|
||||
}
|
||||
|
||||
|
|
@ -486,7 +500,8 @@ open class FSPagerView: UIView,UICollectionViewDataSource,UICollectionViewDelega
|
|||
@objc(scrollToItemAtIndex:animated:)
|
||||
open func scrollToItem(at index: Int, animated: Bool) {
|
||||
guard index < self.numberOfItems else {
|
||||
fatalError("index \(index) is out of range [0...\(self.numberOfItems-1)]")
|
||||
debugPrint("index \(index) is out of range [0...\(self.numberOfItems-1)]")
|
||||
return
|
||||
}
|
||||
let indexPath = { () -> IndexPath in
|
||||
if let indexPath = self.possibleTargetingIndexPath, indexPath.item == index {
|
||||
|
|
@ -513,6 +528,16 @@ open class FSPagerView: UIView,UICollectionViewDataSource,UICollectionViewDelega
|
|||
return indexPath.item
|
||||
}
|
||||
|
||||
/// Returns the visible cell at the specified index.
|
||||
///
|
||||
/// - Parameter index: The index that specifies the position of the cell.
|
||||
/// - Returns: The cell object at the corresponding position or nil if the cell is not visible or index is out of range.
|
||||
@objc(cellForItemAtIndex:)
|
||||
open func cellForItem(at index: Int) -> FSPagerViewCell? {
|
||||
let indexPath = self.nearbyIndexPath(for: index)
|
||||
return self.collectionView.cellForItem(at: indexPath) as? FSPagerViewCell
|
||||
}
|
||||
|
||||
// MARK: - Private functions
|
||||
|
||||
fileprivate func commonInit() {
|
||||
|
|
@ -525,7 +550,7 @@ open class FSPagerView: UIView,UICollectionViewDataSource,UICollectionViewDelega
|
|||
|
||||
// UICollectionView
|
||||
let collectionViewLayout = FSPagerViewLayout()
|
||||
let collectionView = FSPagerViewCollectionView(frame: CGRect.zero, collectionViewLayout: collectionViewLayout)
|
||||
let collectionView = FSPagerCollectionView(frame: CGRect.zero, collectionViewLayout: collectionViewLayout)
|
||||
collectionView.dataSource = self
|
||||
collectionView.delegate = self
|
||||
collectionView.backgroundColor = UIColor.clear
|
||||
|
|
@ -540,7 +565,7 @@ open class FSPagerView: UIView,UICollectionViewDataSource,UICollectionViewDelega
|
|||
return
|
||||
}
|
||||
self.timer = Timer.scheduledTimer(timeInterval: TimeInterval(self.automaticSlidingInterval), target: self, selector: #selector(self.flipNext(sender:)), userInfo: nil, repeats: true)
|
||||
RunLoop.current.add(self.timer!, forMode: .commonModes)
|
||||
RunLoop.current.add(self.timer!, forMode: .common)
|
||||
}
|
||||
|
||||
@objc
|
||||
|
|
@ -579,3 +604,22 @@ open class FSPagerView: UIView,UICollectionViewDataSource,UICollectionViewDelega
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
extension FSPagerView {
|
||||
|
||||
/// Constants indicating the direction of scrolling for the pager view.
|
||||
@objc
|
||||
public enum ScrollDirection: Int {
|
||||
/// The pager view scrolls content horizontally
|
||||
case horizontal
|
||||
/// The pager view scrolls content vertically
|
||||
case vertical
|
||||
}
|
||||
|
||||
/// Requests that FSPagerView use the default value for a given distance.
|
||||
public static let automaticDistance: UInt = 0
|
||||
|
||||
/// Requests that FSPagerView use the default value for a given size.
|
||||
public static let automaticSize: CGSize = .zero
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
//
|
||||
// FSPagerViewObjcCompat.h
|
||||
// FSPagerView
|
||||
//
|
||||
// Created by 丁文超 on 2018/9/18.
|
||||
// Copyright © 2018 Wenchao Ding. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#define FSPagerViewExtern extern
|
||||
|
||||
/**
|
||||
Requests that FSPagerView use the default value for a given distance.
|
||||
*/
|
||||
FSPagerViewExtern NSUInteger const FSPagerViewAutomaticDistance;
|
||||
|
||||
/**
|
||||
Requests that FSPagerView use the default value for a given size.
|
||||
*/
|
||||
FSPagerViewExtern CGSize const FSPagerViewAutomaticSize;
|
||||
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
//
|
||||
// FSPagerViewObjcCompat.m
|
||||
// FSPagerView
|
||||
//
|
||||
// Created by Wenchao Ding on 2018/9/24.
|
||||
// Copyright © 2018 Wenchao Ding. All rights reserved.
|
||||
//
|
||||
|
||||
#import "FSPagerViewObjcCompat.h"
|
||||
|
||||
NSUInteger const FSPagerViewAutomaticDistance = 0;
|
||||
CGSize const FSPagerViewAutomaticSize = { .width = 0, .height = 0 };
|
||||
Loading…
Reference in New Issue