Compare commits

..

No commits in common. "master" and "0.7.2" have entirely different histories.

29 changed files with 210 additions and 448 deletions

4
.gitignore vendored
View File

@ -65,6 +65,4 @@ Carthage/Build
fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots
fastlane/test_output
Index/*
fastlane/test_output

1
.swift-version Normal file
View File

@ -0,0 +1 @@
4.0

View File

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>

View File

@ -7,7 +7,6 @@
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 */; };
@ -44,8 +43,6 @@
/* 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>"; };
@ -102,8 +99,6 @@
F9580B551E5D995400C5B267 /* FSPageViewLayout.swift */,
F9580B561E5D995400C5B267 /* FSPageViewTransformer.swift */,
F95483991E625F1E0069FD7E /* FSPagerViewLayoutAttributes.swift */,
50989DFE2151DB29004DBB4A /* FSPagerViewObjcCompat.h */,
F931E00B2158A1F3001B2A01 /* FSPagerViewObjcCompat.m */,
);
name = Sources;
path = ../Sources;
@ -221,7 +216,7 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0820;
LastUpgradeCheck = 1030;
LastUpgradeCheck = 0900;
ORGANIZATIONNAME = "Wenchao Ding";
TargetAttributes = {
F97C96761E1FDE25002D9E7E = {
@ -241,7 +236,7 @@
};
buildConfigurationList = F97C96721E1FDE25002D9E7E /* Build configuration list for PBXProject "FSPagerViewExample" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = en;
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
@ -301,7 +296,6 @@
F9C694331E40C583007084B6 /* BasicExampleViewController.swift in Sources */,
F9580B5A1E5D995400C5B267 /* FSPagerViewCell.swift in Sources */,
F9580B5B1E5D995400C5B267 /* FSPageViewLayout.swift in Sources */,
F931E00C2158A1F3001B2A01 /* FSPagerViewObjcCompat.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -348,7 +342,6 @@
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++";
@ -358,7 +351,6 @@
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;
@ -366,7 +358,6 @@
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;
@ -399,7 +390,6 @@
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
@ -408,7 +398,6 @@
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++";
@ -418,7 +407,6 @@
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;
@ -426,7 +414,6 @@
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;
@ -451,7 +438,6 @@
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
@ -466,8 +452,8 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.wenchaod.FSPagerViewExample;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 5.0;
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.0;
};
name = Debug;
};
@ -480,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 = Default;
SWIFT_VERSION = 5.0;
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.0;
};
name = Release;
};
@ -494,8 +480,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 = Default;
SWIFT_VERSION = 5.0;
SWIFT_SWIFT3_OBJC_INFERENCE = On;
SWIFT_VERSION = 4.0;
TEST_TARGET_NAME = FSPagerViewExample;
};
name = Debug;
@ -509,8 +495,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 = Default;
SWIFT_VERSION = 5.0;
SWIFT_SWIFT3_OBJC_INFERENCE = On;
SWIFT_VERSION = 4.0;
TEST_TARGET_NAME = FSPagerViewExample;
};
name = Release;

View File

@ -14,7 +14,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}

View File

@ -10,9 +10,8 @@ import UIKit
class BasicExampleViewController: UIViewController,UITableViewDataSource,UITableViewDelegate,FSPagerViewDataSource,FSPagerViewDelegate {
fileprivate let sectionTitles = ["Configurations", "Decelaration Distance", "Item Size", "Interitem Spacing", "Number Of Items"]
fileprivate let sectionTitles = ["Configurations", "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
@ -20,7 +19,7 @@ class BasicExampleViewController: UIViewController,UITableViewDataSource,UITable
@IBOutlet weak var pagerView: FSPagerView! {
didSet {
self.pagerView.register(FSPagerViewCell.self, forCellWithReuseIdentifier: "cell")
self.pagerView.itemSize = FSPagerView.automaticSize
self.pagerView.itemSize = .zero
}
}
@ -38,17 +37,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:
return self.decelerationDistanceOptions.count
case 2,3,4:
case 1,2,3:
return 1
default:
return 0
break
}
return 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
@ -66,25 +65,10 @@ 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 = 1
slider.tag = indexPath.section
slider.value = {
let scale: CGFloat = self.pagerView.itemSize.width/self.pagerView.frame.width
let value: CGFloat = (0.5-scale)*2
@ -92,19 +76,19 @@ class BasicExampleViewController: UIViewController,UITableViewDataSource,UITable
}()
slider.isContinuous = true
return cell
case 3:
case 2:
// Interitem Spacing
let cell = tableView.dequeueReusableCell(withIdentifier: "slider_cell")!
let slider = cell.contentView.subviews.first as! UISlider
slider.tag = 2
slider.tag = indexPath.section
slider.value = Float(self.pagerView.interitemSpacing/20.0)
slider.isContinuous = true
return cell
case 4:
case 3:
// Number Of Items
let cell = tableView.dequeueReusableCell(withIdentifier: "slider_cell")!
let slider = cell.contentView.subviews.first as! UISlider
slider.tag = 3
slider.tag = indexPath.section
slider.minimumValue = 1.0 / 7
slider.maximumValue = 1.0
slider.value = Float(self.numberOfItems) / 7.0
@ -119,7 +103,7 @@ class BasicExampleViewController: UIViewController,UITableViewDataSource,UITable
// MARK:- UITableViewDelegate
func tableView(_ tableView: UITableView, shouldHighlightRowAt indexPath: IndexPath) -> Bool {
return indexPath.section == 0 || indexPath.section == 1
return indexPath.section == 0
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
@ -132,18 +116,6 @@ 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
}
@ -177,14 +149,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 pagerViewWillEndDragging(_ pagerView: FSPagerView, targetIndex: Int) {
self.pageControl.currentPage = targetIndex
}
func pagerViewDidEndScrollAnimation(_ pagerView: FSPagerView) {
self.pageControl.currentPage = pagerView.currentIndex
func pagerViewDidScroll(_ pagerView: FSPagerView) {
guard self.pageControl.currentPage != pagerView.currentIndex else {
return
}
self.pageControl.currentPage = pagerView.currentIndex // Or Use KVO with property "currentIndex"
}
@IBAction func sliderValueChanged(_ sender: UISlider) {

View File

@ -228,8 +228,11 @@ class PageControlExampleViewController: UIViewController,UITableViewDataSource,U
// MARK:- FSPagerViewDelegate
func pagerViewWillEndDragging(_ pagerView: FSPagerView, targetIndex: Int) {
self.pageControl.currentPage = targetIndex
func pagerViewDidScroll(_ pagerView: FSPagerView) {
guard self.pageControl.currentPage != pagerView.currentIndex else {
return
}
self.pageControl.currentPage = pagerView.currentIndex // Or Use KVO with property "currentIndex"
}
// MARK:- Target Actions

View File

@ -27,22 +27,17 @@ class TransformerExampleViewController: UIViewController,FSPagerViewDataSource,F
self.pagerView.transformer = FSPagerViewTransformer(type:type)
switch type {
case .crossFading, .zoomOut, .depth:
self.pagerView.itemSize = FSPagerView.automaticSize
self.pagerView.decelerationDistance = 1
self.pagerView.itemSize = .zero // 'Zero' means fill the size of parent
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
}
}
}
@ -113,3 +108,5 @@ class TransformerExampleViewController: UIViewController,FSPagerViewDataSource,F
}
}

View File

@ -1,7 +1,7 @@
Pod::Spec.new do |s|
s.name = "FSPagerView"
s.version = "0.8.3"
s.version = "0.7.2"
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,8 +14,6 @@ Pod::Spec.new do |s|
s.ios.deployment_target = '8.0'
s.requires_arc = true
s.framework = 'UIKit'
s.source_files = 'Sources/*.{swift,h,m}'
s.swift_version = '5.0'
s.cocoapods_version = '>= 1.4.0'
s.source_files = 'Sources/*.swift'
end

View File

@ -7,8 +7,6 @@
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 */; };
@ -20,8 +18,6 @@
/* 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>"; };
@ -81,8 +77,6 @@
F9580B861E5D9F2B00C5B267 /* FSPageViewLayout.swift */,
F9D7BD291E63DD5F003F6A0E /* FSPagerViewLayoutAttributes.swift */,
F9580B871E5D9F2B00C5B267 /* FSPageViewTransformer.swift */,
50C44A1C2150E7800093B3E9 /* FSPagerViewObjcCompat.h */,
F931E0052158A062001B2A01 /* FSPagerViewObjcCompat.m */,
);
name = Sources;
path = ../Sources;
@ -96,7 +90,6 @@
buildActionMask = 2147483647;
files = (
F9580B7B1E5D9F0600C5B267 /* FSPagerView.h in Headers */,
50C44A1D2150E7800093B3E9 /* FSPagerViewObjcCompat.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -127,24 +120,22 @@
F9580B6D1E5D9F0600C5B267 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1030;
LastUpgradeCheck = 0900;
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 = en;
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = F9580B6C1E5D9F0600C5B267;
productRefGroup = F9580B771E5D9F0600C5B267 /* Products */;
@ -178,7 +169,6 @@
F9580B8C1E5D9F2B00C5B267 /* FSPageViewLayout.swift in Sources */,
F9580B8A1E5D9F2B00C5B267 /* FSPagerView.swift in Sources */,
F9580B8B1E5D9F2B00C5B267 /* FSPagerViewCell.swift in Sources */,
F931E0062158A062001B2A01 /* FSPagerViewObjcCompat.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -189,7 +179,6 @@
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++";
@ -199,7 +188,6 @@
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;
@ -207,7 +195,6 @@
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;
@ -241,7 +228,7 @@
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
SWIFT_VERSION = 4.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
@ -252,7 +239,6 @@
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++";
@ -262,7 +248,6 @@
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;
@ -270,7 +255,6 @@
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;
@ -296,7 +280,7 @@
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 5.0;
SWIFT_VERSION = 4.0;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
@ -307,7 +291,6 @@
F9580B7F1E5D9F0600C5B267 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "";
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = HZF422TY46;
@ -321,15 +304,13 @@
PRODUCT_BUNDLE_IDENTIFIER = com.wenchaod.FSPagerView;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
SWIFT_VERSION = 4.0;
};
name = Debug;
};
F9580B801E5D9F0600C5B267 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "";
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = HZF422TY46;
@ -343,7 +324,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.wenchaod.FSPagerView;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SWIFT_VERSION = 5.0;
SWIFT_VERSION = 4.0;
};
name = Release;
};

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1030"
LastUpgradeVersion = "0900"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@ -26,6 +26,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
@ -36,6 +37,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"

View File

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

View File

@ -14,7 +14,6 @@
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 */; };
@ -45,7 +44,6 @@
/* 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>"; };
@ -53,7 +51,6 @@
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>"; };
@ -124,8 +121,6 @@
F9580B621E5D997200C5B267 /* FSPageViewLayout.swift */,
F9FF349E1E65B38C001E943F /* FSPagerViewLayoutAttributes.swift */,
F9580B631E5D997200C5B267 /* FSPageViewTransformer.swift */,
50989DFD2151DB25004DBB4A /* FSPagerViewObjcCompat.h */,
F931E0092158A1E4001B2A01 /* FSPagerViewObjcCompat.m */,
);
name = Sources;
path = ../Sources;
@ -256,7 +251,7 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0820;
LastUpgradeCheck = 1030;
LastUpgradeCheck = 0900;
ORGANIZATIONNAME = "Wenchao Ding";
TargetAttributes = {
F9C694481E40C6C1007084B6 = {
@ -276,7 +271,7 @@
};
buildConfigurationList = F9EC37141E304A830022B6D6 /* Build configuration list for PBXProject "FSPagerViewExample-Objc" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = en;
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
@ -346,7 +341,6 @@
F93F5E141E319AE8006B7082 /* PageControlExampleViewController.m in Sources */,
F9EC371E1E304A830022B6D6 /* main.m in Sources */,
F9580B661E5D997200C5B267 /* FSPagerView.swift in Sources */,
F931E00A2158A1E4001B2A01 /* FSPagerViewObjcCompat.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -392,8 +386,8 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 5.0;
SWIFT_SWIFT3_OBJC_INFERENCE = On;
SWIFT_VERSION = 4.0;
TEST_TARGET_NAME = "FSPagerViewExample-Objc";
};
name = Debug;
@ -409,8 +403,8 @@
PRODUCT_BUNDLE_IDENTIFIER = "com.wenchaod.FSPagerViewExample-ObjcUITests";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 5.0;
SWIFT_SWIFT3_OBJC_INFERENCE = On;
SWIFT_VERSION = 4.0;
TEST_TARGET_NAME = "FSPagerViewExample-Objc";
};
name = Release;
@ -419,7 +413,6 @@
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++";
@ -429,7 +422,6 @@
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;
@ -437,7 +429,6 @@
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;
@ -468,7 +459,7 @@
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_VERSION = 5.0;
SWIFT_VERSION = 4.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
@ -477,7 +468,6 @@
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++";
@ -487,7 +477,6 @@
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;
@ -495,7 +484,6 @@
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;
@ -520,7 +508,7 @@
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 5.0;
SWIFT_VERSION = 4.0;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
@ -536,7 +524,7 @@
PRODUCT_BUNDLE_IDENTIFIER = "com.wenchaod.FSPagerView-Objc";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 5.0;
SWIFT_VERSION = 4.0;
};
name = Debug;
};
@ -550,7 +538,7 @@
PRODUCT_BUNDLE_IDENTIFIER = "com.wenchaod.FSPagerView-Objc";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 5.0;
SWIFT_VERSION = 4.0;
};
name = Release;
};

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0940"
LastUpgradeVersion = "0830"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@ -8,13 +8,12 @@
#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;
@ -34,18 +33,16 @@
{
[super viewDidLoad];
self.sectionTitles = @[@"Configurations", @"Deceleration Distance", @"Item Size", @"Interitem Spacing", @"Number Of Items"];
self.sectionTitles = @[@"Configurations", @"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 = FSPagerViewAutomaticSize;
self.pagerView.itemSize = self.pagerView.frame.size;
self.pageControl.numberOfPages = self.imageNames.count;
self.pageControl.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight;
self.pageControl.contentInsets = UIEdgeInsetsMake(0, 20, 0, 20);
}
#pragma mark - UITableViewDataSource
@ -61,10 +58,8 @@
case 0:
return self.configurationTitles.count;
case 1:
return self.decelerationDistanceOptions.count;
case 2:
case 3:
case 4:
return 1;
default:
break;
@ -89,52 +84,32 @@
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 = 1;
slider.tag = indexPath.section;
slider.value = ({
CGFloat scale = self.pagerView.itemSize.width/self.pagerView.frame.size.width;
CGFloat value = (0.5-scale)*2;
CGFloat value = (scale-0.5)*2;
value;
});
slider.continuous = YES;
return cell;
}
case 3: {
case 2: {
// Interitem Spacing
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"slider_cell"];
UISlider *slider = cell.contentView.subviews.firstObject;
slider.tag = 2;
slider.tag = indexPath.section;
slider.value = self.pagerView.interitemSpacing / 20.0;
slider.continuous = YES;
return cell;
}
case 4: {
case 3: {
// Number Of Items
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"slider_cell"];
UISlider *slider = cell.contentView.subviews.firstObject;
slider.tag = 3;
slider.tag = indexPath.section;
slider.value = self.numberOfItems / 7.0;
slider.minimumValue = 1.0 / 7;
slider.maximumValue = 1.0;
@ -151,14 +126,14 @@
- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath
{
return indexPath.section == 0 || indexPath.section == 1;
return indexPath.section == 0;
}
- (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;
@ -168,24 +143,6 @@
}
[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;
}
@ -224,16 +181,14 @@
{
[pagerView deselectItemAtIndex:index animated:YES];
[pagerView scrollToItemAtIndex:index animated:YES];
self.pageControl.currentPage = index;
}
- (void)pagerViewWillEndDragging:(FSPagerView *)pagerView targetIndex:(NSInteger)targetIndex
- (void)pagerViewDidScroll:(FSPagerView *)pagerView
{
self.pageControl.currentPage = targetIndex;
}
- (void)pagerViewDidEndScrollAnimation:(FSPagerView *)pagerView
{
self.pageControl.currentPage = pagerView.currentIndex;
if (self.pageControl.currentPage != pagerView.currentIndex) {
self.pageControl.currentPage = pagerView.currentIndex;
}
}
#pragma mark - Target actions

View File

@ -8,7 +8,6 @@
#import "PageControlExampleViewController.h"
#import "FSPagerViewExample_Objc-Swift.h"
#import "FSPagerViewObjcCompat.h"
@interface PageControlExampleViewController () <UITableViewDataSource,UITableViewDelegate,FSPagerViewDataSource,FSPagerViewDelegate>
@ -49,7 +48,7 @@
self.pageControl.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight;
self.pageControl.contentInsets = UIEdgeInsetsMake(0, 20, 0, 20);
self.pagerView.itemSize = FSPagerViewAutomaticSize; // Fill parent
self.pagerView.itemSize = CGSizeZero; // Fill parent
[self.pagerView registerClass:[FSPagerViewCell class] forCellWithReuseIdentifier:@"cell"];
}
@ -160,9 +159,11 @@
#pragma mark - FSPagerViewDelegate
- (void)pagerViewWillEndDragging:(FSPagerView *)pagerView targetIndex:(NSInteger)targetIndex
- (void)pagerViewDidScroll:(FSPagerView *)pagerView
{
self.pageControl.currentPage = targetIndex;
if (self.pageControl.currentPage != pagerView.currentIndex) {
self.pageControl.currentPage = pagerView.currentIndex;
}
}
#pragma mark - Target actions

View File

@ -8,7 +8,6 @@
#import "TransformerExampleViewController.h"
#import "FSPagerViewExample_Objc-Swift.h"
#import "FSPagerViewObjcCompat.h"
@interface TransformerExampleViewController () <UITableViewDataSource,UITableViewDelegate,FSPagerViewDataSource,FSPagerViewDelegate>
@ -149,32 +148,27 @@
case FSPagerViewTransformerTypeCrossFading:
case FSPagerViewTransformerTypeZoomOut:
case FSPagerViewTransformerTypeDepth: {
self.pagerView.itemSize = FSPagerViewAutomaticSize;
self.pagerView.decelerationDistance = 1;
self.pagerView.itemSize = CGSizeZero; // 'Zero' means fill the size of parent
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:

View File

@ -1,4 +1,3 @@
//
// Package.swift
// FSPagerView
@ -25,17 +24,12 @@
// THE SOFTWARE.
import Foundation
import PackageDescription
let package = Package(
name: "FSPagerView",
platforms: [
.iOS(.v9)
],
products: [
.library(name: "FSPagerView", targets: ["FSPagerView"]),
],
targets: [
.target(name: "FSPagerView", path: "Sources", exclude: ["FSPagerViewObjcCompat.h", "FSPagerViewObjcCompat.m"]),
]
dependencies : [],
exclude: []
)

View File

@ -1,6 +1,6 @@
![fspagerview](https://cloud.githubusercontent.com/assets/5186464/24086370/45e7e8dc-0d49-11e7-86aa-139354fe00c5.jpg)
[![Languages](https://img.shields.io/badge/language-swift%204.2%20|%20objc-FF69B4.svg?style=plastic)](#) <br/>
[![Languages](https://img.shields.io/badge/language-swift%20|%20objc-FF69B4.svg?style=plastic)](#) <br/>
[![Platform](https://img.shields.io/badge/platform-iOS%20|%20tvOS-blue.svg?style=plastic)](http://cocoadocs.org/docsets/FSPagerView)
[![Version](https://img.shields.io/cocoapods/v/FSPagerView.svg?style=flat)](http://cocoadocs.org/docsets/FSPagerView)
[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=plastic)](https://github.com/Carthage/Carthage)
@ -46,17 +46,8 @@ 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. When the value of this property is FSPagerViewAutomaticSize, the items fill the entire visible area of the pager view. Default is FSPagerViewAutomaticSize.
The item size of the pager view. .zero means always fill the bounds of the pager view. Default is .zero.
**e.g.**
@ -158,7 +149,7 @@ pagerView.transformer = [[FSPagerViewTransformer alloc] initWithType:FSPagerView
|Cubic|
|------|
| ![9](https://cloud.githubusercontent.com/assets/5186464/23461598/8875080c-fec5-11e6-8db6-6d8864acfcc1.gif) |
```objc
```swift
pagerView.transformer = [[FSPagerViewTransformer alloc] initWithType:FSPagerViewTransformerTypeCubic];
```
---
@ -194,8 +185,7 @@ pageControl.currentPage = 1;
The horizontal alignment of content within the controls bounds. Default is center.
**e.g.**
```objc
```swift
pageControl.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight;
```
@ -290,10 +280,8 @@ FSPageControl *pageControl = [[FSPageControl alloc] initWithFrame:frame2];
3、Register a cell class.
```objc
- (void)viewDidLoad
{
[super viewDidLoad];
[self.pagerView registerClass:[FSPagerViewCell class] forCellWithReuseIdentifier:@"cell"];
- (void)viewDidLoad {
[self.pagerView registerClass:[FSPagerViewCell class] forCellWithReuseIdentifier:@"cell"];
}
```
@ -400,11 +388,12 @@ 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> &nbsp;&nbsp;|&nbsp;&nbsp;
<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> &nbsp;&nbsp;|&nbsp;&nbsp;
<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> &nbsp;&nbsp;|&nbsp;&nbsp;
<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)***

View File

@ -1,6 +1,6 @@
![fspagerview](https://cloud.githubusercontent.com/assets/5186464/24086370/45e7e8dc-0d49-11e7-86aa-139354fe00c5.jpg)
[![Languages](https://img.shields.io/badge/language-swift%205.0%20|%20objc-FF69B4.svg?style=plastic)](#) <br/>
[![Languages](https://img.shields.io/badge/language-swift%20|%20objc-FF69B4.svg?style=plastic)](#) <br/>
[![Platform](https://img.shields.io/badge/platform-iOS%20|%20tvOS-blue.svg?style=plastic)](http://cocoadocs.org/docsets/FSPagerView)
[![Version](https://img.shields.io/cocoapods/v/FSPagerView.svg?style=plastic)](http://cocoadocs.org/docsets/FSPagerView)
[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=plastic)](https://github.com/Carthage/Carthage)
@ -51,17 +51,9 @@ A boolean value indicates whether the pager view has infinite number of items. D
pagerView.isInfinite = true
```
### 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.
The item size of the pager view. .zero means always fill the bounds of the pager view. Default is .zero.
**e.g.**
@ -85,7 +77,7 @@ pagerView.interitemSpacing = 10
| ![1](https://cloud.githubusercontent.com/assets/5186464/22686429/1983b97e-ed5f-11e6-9a32-44c1830df7ac.gif) |
```swift
pagerView.transformer = FSPagerViewTransformer(type: .crossFading)
pagerView.transformer = FSPagerViewTransformer(type: .crossfading)
```
---
@ -96,7 +88,7 @@ pagerView.transformer = FSPagerViewTransformer(type: .crossFading)
| ![2](https://cloud.githubusercontent.com/assets/5186464/22686426/19830862-ed5f-11e6-90be-8fb1319cd125.gif) |
```swift
pagerView.transformer = FSPagerViewTransformer(type: .zoomOut)
pagerView.transformer = FSPagerViewTransformer(type: .zoomout)
```
---
@ -403,7 +395,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> &nbsp;&nbsp;|&nbsp;&nbsp;
<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> &nbsp;&nbsp;|&nbsp;&nbsp;
<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> &nbsp;&nbsp;|&nbsp;&nbsp;
<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>
---
@ -417,4 +409,4 @@ func pagerViewDidEndDecelerating(_ pagerView: FSPagerView)
---
# [Documentation](http://cocoadocs.org/docsets/FSPagerView)
# [Documentation](http://cocoadocs.org/docsets/FSPagerView)

View File

@ -101,12 +101,6 @@
"idiom" : "ipad",
"filename" : "Icon-167.png",
"scale" : "2x"
},
{
"size" : "1024x1024",
"idiom" : "ios-marketing",
"filename" : "icon-1024.png",
"scale" : "1x"
}
],
"info" : {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

View File

@ -8,9 +8,11 @@
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()
@ -18,6 +20,7 @@ open class FSPageControl: UIControl {
}
/// The current page, highlighted by the page control. Default is 0.
@IBInspectable
open var currentPage: Int = 0 {
didSet {
self.setNeedsUpdateIndicators()
@ -25,6 +28,7 @@ open class FSPageControl: UIControl {
}
/// The spacing to use of page indicators in the page control.
@IBInspectable
open var itemSpacing: CGFloat = 6 {
didSet {
self.setNeedsUpdateIndicators()
@ -32,6 +36,7 @@ open class FSPageControl: UIControl {
}
/// The spacing to use between page indicators in the page control.
@IBInspectable
open var interitemSpacing: CGFloat = 6 {
didSet {
self.setNeedsLayout()
@ -39,6 +44,7 @@ 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()
@ -46,25 +52,26 @@ open class FSPageControl: UIControl {
}
/// The horizontal alignment of content within the controls bounds. Default is center.
open override var contentHorizontalAlignment: UIControl.ContentHorizontalAlignment {
open override var contentHorizontalAlignment: UIControlContentHorizontalAlignment {
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: [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] = [:]
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] = [:]
fileprivate weak var contentView: UIView!
@ -110,12 +117,10 @@ 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: UIControl.State = (index == self.currentPage) ? .selected : .normal
let state: UIControlState = (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)
@ -131,7 +136,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: UIControl.State) {
open func setStrokeColor(_ strokeColor: UIColor?, for state: UIControlState) {
guard self.strokeColors[state] != strokeColor else {
return
}
@ -145,7 +150,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: UIControl.State) {
open func setFillColor(_ fillColor: UIColor?, for state: UIControlState) {
guard self.fillColors[state] != fillColor else {
return
}
@ -159,7 +164,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: UIControl.State) {
open func setImage(_ image: UIImage?, for state: UIControlState) {
guard self.images[state] != image else {
return
}
@ -174,7 +179,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: UIControl.State) {
open func setAlpha(_ alpha: CGFloat, for state: UIControlState) {
guard self.alphas[state] != alpha else {
return
}
@ -188,7 +193,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: UIControl.State) {
open func setPath(_ path: UIBezierPath?, for state: UIControlState) {
guard self.paths[state] != path else {
return
}
@ -235,8 +240,8 @@ open class FSPageControl: UIControl {
}
fileprivate func updateIndicatorAttributes(for layer: CAShapeLayer) {
let index = self.indicatorLayers.firstIndex(of: layer)
let state: UIControl.State = index == self.currentPage ? .selected : .normal
let index = self.indicatorLayers.index(of: layer)
let state: UIControlState = index == self.currentPage ? .selected : .normal
if let image = self.images[state] {
layer.strokeColor = nil
layer.fillColor = nil
@ -295,7 +300,7 @@ open class FSPageControl: UIControl {
}
extension UIControl.State: Hashable {
extension UIControlState: Hashable {
public var hashValue: Int {
return Int((6777*self.rawValue+3777)%UInt(UInt16.max))
}

View File

@ -14,16 +14,19 @@ class FSPagerViewLayout: UICollectionViewLayout {
internal var leadingSpacing: CGFloat = 0
internal var itemSpacing: CGFloat = 0
internal var needsReprepare = true
internal var scrollDirection: FSPagerView.ScrollDirection = .horizontal
internal var scrollDirection: FSPagerViewScrollDirection = .horizontal
open override class var layoutAttributesClass: AnyClass {
return FSPagerViewLayoutAttributes.self
get {
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
@ -42,7 +45,7 @@ class FSPagerViewLayout: UICollectionViewLayout {
deinit {
#if !os(tvOS)
NotificationCenter.default.removeObserver(self, name: UIDevice.orientationDidChangeNotification, object: nil)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
#endif
}
@ -126,7 +129,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 * abs(origin+maxPosition), .leastNonzeroMagnitude) {
while origin-maxPosition <= max(CGFloat(100.0) * .ulpOfOne * fabs(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)
@ -140,7 +143,6 @@ 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
@ -149,48 +151,39 @@ class FSPagerViewLayout: UICollectionViewLayout {
}
override open func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {
guard let collectionView = self.collectionView, let pagerView = self.pagerView else {
guard let collectionView = self.collectionView 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 boundedOffset = collectionView.contentSize.width-self.itemSpacing
return calculateTargetOffset(by: proposedContentOffset.x, boundedOffset: boundedOffset)
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 proposedContentOffsetY: CGFloat = {
if self.scrollDirection == .horizontal {
return proposedContentOffset.y
}
let boundedOffset = collectionView.contentSize.height-self.itemSpacing
return calculateTargetOffset(by: proposedContentOffset.y, boundedOffset: boundedOffset)
let translation = -collectionView.panGestureRecognizer.translation(in: collectionView).y
var offset: CGFloat = round(proposedContentOffset.y/self.itemSpacing)*self.itemSpacing
let minFlippingDistance = min(0.5 * self.itemSpacing,150)
let originalContentOffsetY = collectionView.contentOffset.y - translation
if abs(translation) <= minFlippingDistance {
if abs(velocity.y) >= 0.3 && abs(proposedContentOffset.y-originalContentOffsetY) <= self.itemSpacing*0.5 {
offset += self.itemSpacing * (velocity.y)/abs(velocity.y)
}
}
return offset
}()
proposedContentOffset = CGPoint(x: proposedContentOffsetX, y: proposedContentOffsetY)
return proposedContentOffset
@ -257,7 +250,7 @@ class FSPagerViewLayout: UICollectionViewLayout {
fileprivate func commonInit() {
#if !os(tvOS)
NotificationCenter.default.addObserver(self, selector: #selector(didReceiveNotification(notification:)), name: UIDevice.orientationDidChangeNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(didReceiveNotification(notification:)), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
#endif
}
@ -265,11 +258,12 @@ class FSPagerViewLayout: UICollectionViewLayout {
guard let collectionView = self.collectionView, let pagerView = self.pagerView else {
return
}
let currentIndex = pagerView.currentIndex
let newIndexPath = IndexPath(item: currentIndex, section: pagerView.isInfinite ? self.numberOfSections/2 : 0)
let currentIndex = max(0, min(pagerView.currentIndex, pagerView.numberOfItems - 1))
let newIndexPath = IndexPath(item: currentIndex, section: self.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?) {

View File

@ -26,8 +26,8 @@ open class FSPagerViewTransformer: NSObject {
open internal(set) weak var pagerView: FSPagerView?
open internal(set) var type: FSPagerViewTransformerType
@objc open var minimumScale: CGFloat = 0.65
@objc open var minimumAlpha: CGFloat = 0.6
open var minimumScale: CGFloat = 0.65
open var minimumAlpha: CGFloat = 0.6
@objc
public init(type: FSPagerViewTransformerType) {

View File

@ -1,5 +1,5 @@
//
// FSPagerCollectionView.swift
// FSPagerViewCollectionView.swift
// FSPagerView
//
// Created by Wenchao Ding on 24/12/2016.
@ -10,7 +10,11 @@
import UIKit
class FSPagerCollectionView: UICollectionView {
class FSPagerViewCollectionView: UICollectionView {
fileprivate var pagerView: FSPagerView? {
return self.superview?.superview as? FSPagerView
}
#if !os(tvOS)
override var scrollsToTop: Bool {
@ -48,7 +52,7 @@ class FSPagerCollectionView: UICollectionView {
fileprivate func commonInit() {
self.contentInset = .zero
self.decelerationRate = UIScrollView.DecelerationRate.fast
self.decelerationRate = UIScrollViewDecelerationRateFast
self.showsVerticalScrollIndicator = false
self.showsHorizontalScrollIndicator = false
if #available(iOS 10.0, *) {

View File

@ -74,25 +74,29 @@ 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.
@objc
open var scrollDirection: FSPagerView.ScrollDirection = .horizontal {
open var scrollDirection: FSPagerViewScrollDirection = .horizontal {
didSet {
self.collectionViewLayout.forceInvalidate()
}
}
/// The time interval of automatic sliding. 0 means disabling automatic sliding. Default is 0.
@IBInspectable
open var automaticSlidingInterval: CGFloat = 0.0 {
didSet {
self.cancelTimer()
@ -103,20 +107,23 @@ 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. 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 {
/// 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 {
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
@ -124,41 +131,24 @@ 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.
open var alwaysBounceHorizontal: Bool {
set { self.collectionView.alwaysBounceHorizontal = newValue }
get { return self.collectionView.alwaysBounceHorizontal }
@IBInspectable
open var alwaysBounceHorizontal: Bool = false {
didSet {
self.collectionView.alwaysBounceHorizontal = self.alwaysBounceHorizontal;
}
}
/// A Boolean value that determines whether bouncing always occurs when vertical scrolling reaches the end of the content view.
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 {
@IBInspectable
open var alwaysBounceVertical: Bool = false {
didSet {
self.reloadData()
self.collectionView.alwaysBounceVertical = self.alwaysBounceVertical;
}
}
/// The background view of the pager view.
@IBInspectable
open var backgroundView: UIView? {
didSet {
if let backgroundView = self.backgroundView {
@ -183,32 +173,38 @@ 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(self.numberOfItems))
return fmod(CGFloat(scrollOffset), CGFloat(Double(self.numberOfItems)))
}
/// The underlying gesture recognizer for pan gestures.
@objc
open var panGestureRecognizer: UIPanGestureRecognizer {
return self.collectionView.panGestureRecognizer
}
@objc open fileprivate(set) dynamic var currentIndex: Int = 0
@objc open internal(set) dynamic var currentIndex: Int = 0
// MARK: - Private properties
internal weak var collectionViewLayout: FSPagerViewLayout!
internal weak var collectionView: FSPagerCollectionView!
internal weak var collectionView: FSPagerViewCollectionView!
internal weak var contentView: UIView!
internal var timer: Timer?
internal var numberOfItems: Int = 0
internal var numberOfSections: Int = 0
@ -240,15 +236,10 @@ 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) {
@ -277,14 +268,11 @@ 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)
@ -292,13 +280,11 @@ 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 {
@ -379,7 +365,7 @@ open class FSPagerView: UIView,UICollectionViewDataSource,UICollectionViewDelega
}
public func scrollViewDidScroll(_ scrollView: UIScrollView) {
if !self.isPossiblyRotating && self.numberOfItems > 0 {
if self.numberOfItems > 0 {
// In case someone is using KVO
let currentIndex = lround(Double(self.scrollOffset)) % self.numberOfItems
if (currentIndex != self.currentIndex) {
@ -477,7 +463,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: UICollectionView.ScrollPosition = self.scrollDirection == .horizontal ? .centeredHorizontally : .centeredVertically
let scrollPosition: UICollectionViewScrollPosition = self.scrollDirection == .horizontal ? .centeredHorizontally : .centeredVertically
self.collectionView.selectItem(at: indexPath, animated: animated, scrollPosition: scrollPosition)
}
@ -500,8 +486,7 @@ open class FSPagerView: UIView,UICollectionViewDataSource,UICollectionViewDelega
@objc(scrollToItemAtIndex:animated:)
open func scrollToItem(at index: Int, animated: Bool) {
guard index < self.numberOfItems else {
debugPrint("index \(index) is out of range [0...\(self.numberOfItems-1)]")
return
fatalError("index \(index) is out of range [0...\(self.numberOfItems-1)]")
}
let indexPath = { () -> IndexPath in
if let indexPath = self.possibleTargetingIndexPath, indexPath.item == index {
@ -528,16 +513,6 @@ 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() {
@ -550,7 +525,7 @@ open class FSPagerView: UIView,UICollectionViewDataSource,UICollectionViewDelega
// UICollectionView
let collectionViewLayout = FSPagerViewLayout()
let collectionView = FSPagerCollectionView(frame: CGRect.zero, collectionViewLayout: collectionViewLayout)
let collectionView = FSPagerViewCollectionView(frame: CGRect.zero, collectionViewLayout: collectionViewLayout)
collectionView.dataSource = self
collectionView.delegate = self
collectionView.backgroundColor = UIColor.clear
@ -565,7 +540,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: .common)
RunLoop.current.add(self.timer!, forMode: .commonModes)
}
@objc
@ -604,22 +579,3 @@ 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
}

View File

@ -1,23 +0,0 @@
//
// 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;

View File

@ -1,12 +0,0 @@
//
// 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 };