1. Add 'removesInfiniteLoopForSingleItem' for FSPagerView

2. Add 'alwaysBounceVertical' and 'alwaysBounceHorizontal' for FSPagerView
3. Add 'hidesForSinglePage' for FSPageControl
4. Update Examples
This commit is contained in:
丁文超 2017-09-07 11:45:27 +08:00
parent fc48cda535
commit fcef559931
10 changed files with 149 additions and 69 deletions

View File

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11762" systemVersion="16D32" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="65m-zG-Zjb">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="65m-zG-Zjb">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
<capability name="Aspect ratio constraints" minToolsVersion="5.1"/>
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
@ -129,6 +129,11 @@
<constraints>
<constraint firstAttribute="width" secondItem="CTG-eH-B7s" secondAttribute="height" multiplier="375:193" id="rZx-r3-VSz"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="alwaysBounceHorizontal" value="YES"/>
<userDefinedRuntimeAttribute type="boolean" keyPath="removesInfiniteLoopForSingleItem" value="YES"/>
<userDefinedRuntimeAttribute type="boolean" keyPath="isInfinite" value="YES"/>
</userDefinedRuntimeAttributes>
<connections>
<outlet property="dataSource" destination="8S4-ui-raa" id="LYI-MJ-msM"/>
<outlet property="delegate" destination="8S4-ui-raa" id="ZXc-ha-CLU"/>
@ -139,8 +144,11 @@
<constraints>
<constraint firstAttribute="height" constant="25" id="wm0-Qk-cZE"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="hidesForSinglePage" value="YES"/>
</userDefinedRuntimeAttributes>
</view>
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="grouped" separatorStyle="default" rowHeight="44" sectionHeaderHeight="18" sectionFooterHeight="18" translatesAutoresizingMaskIntoConstraints="NO" id="yIp-0M-Jf9">
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" delaysContentTouches="NO" dataMode="prototypes" style="grouped" separatorStyle="default" rowHeight="44" sectionHeaderHeight="18" sectionFooterHeight="18" translatesAutoresizingMaskIntoConstraints="NO" id="yIp-0M-Jf9">
<rect key="frame" x="0.0" y="257" width="375" height="410"/>
<color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
<constraints>
@ -148,7 +156,7 @@
</constraints>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="cell" textLabel="tk3-eI-HIS" style="IBUITableViewCellStyleDefault" id="VNC-TS-zto">
<rect key="frame" x="0.0" y="55.5" width="375" height="44"/>
<rect key="frame" x="0.0" y="56" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="VNC-TS-zto" id="zR3-db-xZl">
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
@ -165,10 +173,10 @@
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="slider_cell" id="RaL-gg-XJm">
<rect key="frame" x="0.0" y="99.5" width="375" height="44"/>
<rect key="frame" x="0.0" y="100" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="RaL-gg-XJm" id="i4q-nX-6cD">
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="43"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<slider opaque="NO" tag="100" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="1" minValue="0.0" maxValue="1" translatesAutoresizingMaskIntoConstraints="NO" id="bXH-0y-EZe">
@ -250,7 +258,7 @@
</constraints>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="cell" textLabel="zyL-iX-55x" style="IBUITableViewCellStyleDefault" id="5d8-B4-K8u">
<rect key="frame" x="0.0" y="55.5" width="375" height="44"/>
<rect key="frame" x="0.0" y="56" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="5d8-B4-K8u" id="uyz-07-btn">
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
@ -325,7 +333,7 @@
</constraints>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="cell" textLabel="BsM-5g-055" style="IBUITableViewCellStyleDefault" id="xKM-zP-mhA">
<rect key="frame" x="0.0" y="55.5" width="375" height="44"/>
<rect key="frame" x="0.0" y="56" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="xKM-zP-mhA" id="e6f-eC-LPJ">
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
@ -342,10 +350,10 @@
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="slider_cell" id="5vo-WJ-LAV">
<rect key="frame" x="0.0" y="99.5" width="375" height="44"/>
<rect key="frame" x="0.0" y="100" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="5vo-WJ-LAV" id="4El-3j-sQo">
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="43"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<slider opaque="NO" tag="100" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="1" minValue="0.0" maxValue="1" translatesAutoresizingMaskIntoConstraints="NO" id="po6-ni-APz">

View File

@ -10,9 +10,10 @@ import UIKit
class BasicExampleViewController: UIViewController,UITableViewDataSource,UITableViewDelegate,FSPagerViewDataSource,FSPagerViewDelegate {
fileprivate let sectionTitles = ["Configurations", "Item Size", "Interitem Spacing"]
fileprivate let sectionTitles = ["Configurations", "Item Size", "Interitem Spacing", "Number Of Items"]
fileprivate let configurationTitles = ["Automatic sliding","Infinite"]
fileprivate let imageNames = ["1.jpg","2.jpg","3.jpg","4.jpg","5.jpg","6.jpg","7.jpg"]
fileprivate var numberOfItems = 7
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var pagerView: FSPagerView! {
@ -30,18 +31,6 @@ class BasicExampleViewController: UIViewController,UITableViewDataSource,UITable
}
}
@IBAction func sliderValueChanged(_ sender: UISlider) {
switch sender.tag {
case 1:
let newScale = 0.5+CGFloat(sender.value)*0.5 // [0.5 - 1.0]
self.pagerView.itemSize = self.pagerView.frame.size.applying(CGAffineTransform(scaleX: newScale, y: newScale))
case 2:
self.pagerView.interitemSpacing = CGFloat(sender.value) * 20 // [0 - 20]
default:
break
}
}
// MARK:- UITableViewDataSource
func numberOfSections(in tableView: UITableView) -> Int {
@ -53,7 +42,7 @@ class BasicExampleViewController: UIViewController,UITableViewDataSource,UITable
switch section {
case 0:
return self.configurationTitles.count
case 1,2:
case 1,2,3:
return 1
default:
break
@ -85,6 +74,7 @@ class BasicExampleViewController: UIViewController,UITableViewDataSource,UITable
let value: CGFloat = (0.5-scale)*2
return Float(value)
}()
slider.isContinuous = true
return cell
case 2:
// Interitem Spacing
@ -92,6 +82,17 @@ class BasicExampleViewController: UIViewController,UITableViewDataSource,UITable
let slider = cell.contentView.subviews.first as! UISlider
slider.tag = indexPath.section
slider.value = Float(self.pagerView.interitemSpacing.divided(by: 20.0))
slider.isContinuous = true
return cell
case 3:
// Number Of Items
let cell = tableView.dequeueReusableCell(withIdentifier: "slider_cell")!
let slider = cell.contentView.subviews.first as! UISlider
slider.tag = indexPath.section
slider.minimumValue = 1.0 / 7
slider.maximumValue = 1.0
slider.value = Float(self.numberOfItems) / 7.0
slider.isContinuous = false
return cell
default:
break
@ -131,7 +132,7 @@ class BasicExampleViewController: UIViewController,UITableViewDataSource,UITable
// MARK:- FSPagerView DataSource
public func numberOfItems(in pagerView: FSPagerView) -> Int {
return self.imageNames.count
return self.numberOfItems
}
public func pagerView(_ pagerView: FSPagerView, cellForItemAt index: Int) -> FSPagerViewCell {
@ -158,6 +159,21 @@ class BasicExampleViewController: UIViewController,UITableViewDataSource,UITable
self.pageControl.currentPage = pagerView.currentIndex // Or Use KVO with property "currentIndex"
}
@IBAction func sliderValueChanged(_ sender: UISlider) {
switch sender.tag {
case 1:
let newScale = 0.5+CGFloat(sender.value)*0.5 // [0.5 - 1.0]
self.pagerView.itemSize = self.pagerView.frame.size.applying(CGAffineTransform(scaleX: newScale, y: newScale))
case 2:
self.pagerView.interitemSpacing = CGFloat(sender.value) * 20 // [0 - 20]
case 3:
self.numberOfItems = Int(roundf(sender.value*7.0))
self.pageControl.numberOfPages = self.numberOfItems
self.pagerView.reloadData()
default:
break
}
}
}

View File

@ -130,6 +130,7 @@ class PageControlExampleViewController: UIViewController,UITableViewDataSource,U
self.pageControl.numberOfPages = self.imageNames.count
self.pageControl.contentHorizontalAlignment = .right
self.pageControl.contentInsets = UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 20)
self.pageControl.hidesForSinglePage = true
}
}

View File

@ -1,7 +1,7 @@
Pod::Spec.new do |s|
s.name = "FSPagerView"
s.version = "0.5.5"
s.version = "0.6.0"
s.summary = "FSPagerView is an elegant Screen Slide Library for making Banner、Product Show、Welcome/Guide Pages、Screen/ViewController Sliders."
s.homepage = "https://github.com/WenchaoD/FSPagerView"

View File

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

View File

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11762" systemVersion="16C67" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="65m-zG-Zjb">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="65m-zG-Zjb">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
<capability name="Aspect ratio constraints" minToolsVersion="5.1"/>
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
@ -142,7 +142,7 @@
</constraints>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="cell" textLabel="zyL-iX-55x" style="IBUITableViewCellStyleDefault" id="5d8-B4-K8u">
<rect key="frame" x="0.0" y="55.5" width="375" height="44"/>
<rect key="frame" x="0.0" y="56" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="5d8-B4-K8u" id="uyz-07-btn">
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
@ -217,7 +217,7 @@
</constraints>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="cell" textLabel="BsM-5g-055" style="IBUITableViewCellStyleDefault" id="xKM-zP-mhA">
<rect key="frame" x="0.0" y="55.5" width="375" height="44"/>
<rect key="frame" x="0.0" y="56" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="xKM-zP-mhA" id="e6f-eC-LPJ">
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
@ -234,10 +234,10 @@
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="slider_cell" id="5vo-WJ-LAV">
<rect key="frame" x="0.0" y="99.5" width="375" height="44"/>
<rect key="frame" x="0.0" y="100" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="5vo-WJ-LAV" id="4El-3j-sQo">
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="43"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<slider opaque="NO" tag="100" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="1" minValue="0.0" maxValue="1" translatesAutoresizingMaskIntoConstraints="NO" id="po6-ni-APz">
@ -311,6 +311,10 @@
<constraints>
<constraint firstAttribute="width" secondItem="ch4-Dh-rc6" secondAttribute="height" multiplier="375:193" id="q7s-YA-wpI"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="alwaysBounceHorizontal" value="YES"/>
<userDefinedRuntimeAttribute type="boolean" keyPath="removesInfiniteLoopForSingleItem" value="YES"/>
</userDefinedRuntimeAttributes>
<connections>
<outlet property="dataSource" destination="7zq-aB-pr6" id="PzF-f2-zA4"/>
<outlet property="delegate" destination="7zq-aB-pr6" id="RZx-1y-bYh"/>
@ -321,6 +325,9 @@
<constraints>
<constraint firstAttribute="height" constant="25" id="awi-gp-ifB"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="hidesForSinglePage" value="YES"/>
</userDefinedRuntimeAttributes>
</view>
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="grouped" separatorStyle="default" rowHeight="44" sectionHeaderHeight="18" sectionFooterHeight="18" translatesAutoresizingMaskIntoConstraints="NO" id="226-3E-RRx">
<rect key="frame" x="0.0" y="257" width="375" height="410"/>
@ -330,7 +337,7 @@
</constraints>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="cell" textLabel="LWk-3K-WmP" style="IBUITableViewCellStyleDefault" id="wPj-3l-HCm">
<rect key="frame" x="0.0" y="55.5" width="375" height="44"/>
<rect key="frame" x="0.0" y="56" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="wPj-3l-HCm" id="QTf-kp-J16">
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
@ -347,10 +354,10 @@
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="slider_cell" id="nbi-ZR-nDk">
<rect key="frame" x="0.0" y="99.5" width="375" height="44"/>
<rect key="frame" x="0.0" y="100" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="nbi-ZR-nDk" id="cD9-AG-y92">
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="43"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<slider opaque="NO" tag="100" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="1" minValue="0.0" maxValue="1" translatesAutoresizingMaskIntoConstraints="NO" id="WnD-c9-GfM">

View File

@ -15,6 +15,7 @@
@property (strong, nonatomic) NSArray<NSString *> *sectionTitles;
@property (strong, nonatomic) NSArray<NSString *> *configurationTitles;
@property (strong, nonatomic) NSArray<NSString *> *imageNames;
@property (assign, nonatomic) NSInteger numberOfItems;
@property (weak , nonatomic) IBOutlet UITableView *tableView;
@property (weak , nonatomic) IBOutlet FSPagerView *pagerView;
@ -32,9 +33,10 @@
{
[super viewDidLoad];
self.sectionTitles = @[@"Configurations", @"Item Size", @"Interitem Spacing"];
self.sectionTitles = @[@"Configurations", @"Item Size", @"Interitem Spacing", @"Number Of Items"];
self.configurationTitles = @[@"Automatic sliding", @"Infinite"];
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;
@ -53,12 +55,13 @@
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
switch (section) {
case 0:
case 0:
return self.configurationTitles.count;
case 1:
case 2:
case 1:
case 2:
case 3:
return 1;
default:
default:
break;
}
return 0;
@ -90,6 +93,7 @@
CGFloat value = (scale-0.5)*2;
value;
});
slider.continuous = YES;
return cell;
}
case 2: {
@ -98,6 +102,18 @@
UISlider *slider = cell.contentView.subviews.firstObject;
slider.tag = indexPath.section;
slider.value = self.pagerView.interitemSpacing / 20.0;
slider.continuous = YES;
return cell;
}
case 3: {
// Number Of Items
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"slider_cell"];
UISlider *slider = cell.contentView.subviews.firstObject;
slider.tag = indexPath.section;
slider.value = self.numberOfItems / 7.0;
slider.minimumValue = 1.0 / 7;
slider.maximumValue = 1.0;
slider.continuous = NO;
return cell;
}
default:
@ -146,7 +162,7 @@
- (NSInteger)numberOfItemsInPagerView:(FSPagerView *)pagerView
{
return self.imageNames.count;
return self.numberOfItems;
}
- (FSPagerViewCell *)pagerView:(FSPagerView *)pagerView cellForItemAtIndex:(NSInteger)index
@ -189,6 +205,12 @@
self.pagerView.interitemSpacing = sender.value * 20; // [0 - 20]
break;
}
case 3: {
self.numberOfItems = roundf(sender.value * 7);
self.pageControl.numberOfPages = self.numberOfItems;
[self.pagerView reloadData];
break;
}
default:
break;
}

View File

@ -58,6 +58,14 @@ open class FSPageControl: UIControl {
}
}
/// 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] = [:]
@ -71,17 +79,6 @@ open class FSPageControl: UIControl {
fileprivate var needsCreateIndicators = false
fileprivate var indicatorLayers = [CAShapeLayer]()
fileprivate var runLoopObserver: CFRunLoopObserver?
fileprivate var runLoopCallback: CFRunLoopObserverCallBack = {
(observer: CFRunLoopObserver?, activity: CFRunLoopActivity, info: UnsafeMutableRawPointer?) -> Void in
guard let info = info else {
return
}
let pageControl = Unmanaged<FSPageControl>.fromOpaque(info).takeUnretainedValue()
pageControl.createIndicatorsIfNecessary()
pageControl.updateIndicatorsIfNecessary()
}
public override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
@ -92,10 +89,6 @@ open class FSPageControl: UIControl {
commonInit()
}
deinit {
CFRunLoopRemoveObserver(CFRunLoopGetCurrent(), self.runLoopObserver, .commonModes);
}
open override func layoutSubviews() {
super.layoutSubviews()
self.contentView.frame = {
@ -218,18 +211,14 @@ open class FSPageControl: UIControl {
self.addSubview(view)
self.contentView = view
// RunLoop
let runLoop = CFRunLoopGetCurrent()
let activities: CFRunLoopActivity = [.entry,.afterWaiting]
var context = CFRunLoopObserverContext(version: 0, info: Unmanaged.passUnretained(self).toOpaque(), retain: nil, release: nil, copyDescription: nil)
self.runLoopObserver = CFRunLoopObserverCreate(nil, activities.rawValue, true, Int.max, self.runLoopCallback, &context)
CFRunLoopAddObserver(runLoop, self.runLoopObserver, .commonModes)
}
fileprivate func setNeedsUpdateIndicators() {
self.needsUpdateIndicators = true
self.setNeedsLayout()
DispatchQueue.main.async {
self.updateIndicatorsIfNecessary()
}
}
fileprivate func updateIndicatorsIfNecessary() {
@ -240,8 +229,12 @@ open class FSPageControl: UIControl {
return
}
self.needsUpdateIndicators = false
self.indicatorLayers.forEach { (layer) in
self.updateIndicatorAttributes(for: layer)
self.contentView.isHidden = self.hidesForSinglePage && self.numberOfPages <= 1
if !self.contentView.isHidden {
self.indicatorLayers.forEach { (layer) in
layer.isHidden = false
self.updateIndicatorAttributes(for: layer)
}
}
}
@ -274,6 +267,9 @@ open class FSPageControl: UIControl {
fileprivate func setNeedsCreateIndicators() {
self.needsCreateIndicators = true
DispatchQueue.main.async {
self.createIndicatorsIfNecessary()
}
}
fileprivate func createIndicatorsIfNecessary() {
@ -281,6 +277,11 @@ open class FSPageControl: UIControl {
return
}
self.needsCreateIndicators = false
CATransaction.begin()
CATransaction.setDisableActions(true)
if self.currentPage >= self.numberOfPages {
self.currentPage = self.numberOfPages - 1
}
self.indicatorLayers.forEach { (layer) in
layer.removeFromSuperlayer()
}
@ -293,6 +294,7 @@ open class FSPageControl: UIControl {
}
self.setNeedsUpdateIndicators()
self.updateIndicatorsIfNecessary()
CATransaction.commit()
}
}

View File

@ -258,11 +258,12 @@ class FSPagerViewLayout: UICollectionViewLayout {
guard let collectionView = self.collectionView, let pagerView = self.pagerView else {
return
}
let currentIndex = pagerView.currentIndex
let currentIndex = 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

@ -137,6 +137,21 @@ open class FSPagerView: UIView,UICollectionViewDataSource,UICollectionViewDelega
}
}
/// 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;
}
}
/// 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 {
didSet {
self.collectionView.alwaysBounceVertical = self.alwaysBounceVertical;
}
}
/// The background view of the pager view.
@IBInspectable
@ -167,6 +182,14 @@ open class FSPagerView: UIView,UICollectionViewDataSource,UICollectionViewDelega
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.
open var scrollOffset: CGFloat {
let contentOffset = max(self.collectionView.contentOffset.x, self.collectionView.contentOffset.y)
@ -179,7 +202,7 @@ open class FSPagerView: UIView,UICollectionViewDataSource,UICollectionViewDelega
return self.collectionView.panGestureRecognizer
}
open fileprivate(set) dynamic var currentIndex: Int = 0
open internal(set) dynamic var currentIndex: Int = 0
// MARK: - Private properties
@ -277,7 +300,7 @@ open class FSPagerView: UIView,UICollectionViewDataSource,UICollectionViewDelega
guard self.numberOfItems > 0 else {
return 0;
}
self.numberOfSections = self.isInfinite ? Int(Int16.max)/self.numberOfItems : 1
self.numberOfSections = self.isInfinite && (self.numberOfItems > 1 || !self.removesInfiniteLoopForSingleItem) ? Int(Int16.max)/self.numberOfItems : 1
return self.numberOfSections
}