12 Commits

Author SHA1 Message Date
hryk224 30c3562ae4 Small changed 2017-02-27 13:48:04 +09:00
hryk224 1e0ae10e2d Merge pull request #12 from hryk224/1.4.0
1.3.1
2017-02-17 05:04:51 +09:00
hyyk224 105846f1d2 1.3.1 2017-02-17 05:04:12 +09:00
hryk224 bcc954d105 Update podspec 2017-01-12 10:40:48 +09:00
hryk224 543b75cf56 Merge pull request #11 from jwardle/master
selectItem implementation
2017-01-12 10:38:49 +09:00
James Wardle 4bd0209ccb Update InfiniteCollectionView.swift
~ Enhanced the implementation to correct the index.
2017-01-10 21:59:52 +00:00
James Wardle 6fcd6a52e2 Update InfiniteCollectionView.swift
+ Added selectItem override to allow programatic selection of items - previously this was not considered and broken.
2017-01-09 22:01:02 +00:00
hryk224 d5afefb36d Updated 1.2.1 2017-01-05 11:14:02 +09:00
hryk224 118f9c3a45 Small changed 2017-01-05 11:12:06 +09:00
hryk224 af34834fdf Merge pull request #9 from hryk224/fix/remove_cellwidth
Removed `var cellWidth`
2016-12-05 23:38:57 +09:00
hyyk224 b82efbc483 Add deprecated message for warning 2016-12-05 23:38:21 +09:00
hryk224 037a932409 Removed unneeded property 2016-11-17 14:51:26 +09:00
19 changed files with 401 additions and 299 deletions
+2 -1
View File
@@ -20,4 +20,5 @@ DerivedData
*.ipa
*.app
*.xccheckout
*.xccheckout
sort-Xcode-project-file
+30 -14
View File
@@ -86,8 +86,8 @@
isa = PBXGroup;
children = (
935BD6C71CE26EB600E5FDF7 /* Example */,
935BD6C61CE26EB600E5FDF7 /* Products */,
EDA05AD11D92901900F7C2C5 /* Frameworks */,
935BD6C61CE26EB600E5FDF7 /* Products */,
);
sourceTree = "<group>";
};
@@ -102,22 +102,38 @@
935BD6C71CE26EB600E5FDF7 /* Example */ = {
isa = PBXGroup;
children = (
ED510E6D1DDD513200470C8B /* Pattern1 */,
ED510E6E1DDD513F00470C8B /* Pattern2 */,
935BD6C81CE26EB600E5FDF7 /* AppDelegate.swift */,
935BD6CF1CE26EB600E5FDF7 /* Assets.xcassets */,
935BD6DA1CE26F0B00E5FDF7 /* ImageCollectionViewCell.swift */,
935BD6DB1CE26F0B00E5FDF7 /* ImageCollectionViewCell.xib */,
935BD6DC1CE26F0B00E5FDF7 /* MainViewController.swift */,
935BD6DD1CE26F0B00E5FDF7 /* Pattern1.storyboard */,
935BD6DE1CE26F0B00E5FDF7 /* Pattern1ViewController.swift */,
935BD6DF1CE26F0B00E5FDF7 /* Pattern2.storyboard */,
935BD6E01CE26F0B00E5FDF7 /* Pattern2ViewController.swift */,
935BD6CC1CE26EB600E5FDF7 /* Main.storyboard */,
935BD6CF1CE26EB600E5FDF7 /* Assets.xcassets */,
935BD6D11CE26EB600E5FDF7 /* LaunchScreen.storyboard */,
935BD6D41CE26EB600E5FDF7 /* Info.plist */,
935BD6D11CE26EB600E5FDF7 /* LaunchScreen.storyboard */,
935BD6CC1CE26EB600E5FDF7 /* Main.storyboard */,
935BD6DC1CE26F0B00E5FDF7 /* MainViewController.swift */,
);
path = Example;
sourceTree = "<group>";
};
ED510E6D1DDD513200470C8B /* Pattern1 */ = {
isa = PBXGroup;
children = (
935BD6DD1CE26F0B00E5FDF7 /* Pattern1.storyboard */,
935BD6DE1CE26F0B00E5FDF7 /* Pattern1ViewController.swift */,
);
name = Pattern1;
sourceTree = "<group>";
};
ED510E6E1DDD513F00470C8B /* Pattern2 */ = {
isa = PBXGroup;
children = (
935BD6DF1CE26F0B00E5FDF7 /* Pattern2.storyboard */,
935BD6E01CE26F0B00E5FDF7 /* Pattern2ViewController.swift */,
);
name = Pattern2;
sourceTree = "<group>";
};
EDA05AD11D92901900F7C2C5 /* Frameworks */ = {
isa = PBXGroup;
children = (
@@ -211,12 +227,12 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
935BD6E61CE26F0B00E5FDF7 /* Pattern2.storyboard in Resources */,
935BD6D31CE26EB600E5FDF7 /* LaunchScreen.storyboard in Resources */,
935BD6D01CE26EB600E5FDF7 /* Assets.xcassets in Resources */,
935BD6E41CE26F0B00E5FDF7 /* Pattern1.storyboard in Resources */,
935BD6E21CE26F0B00E5FDF7 /* ImageCollectionViewCell.xib in Resources */,
935BD6D31CE26EB600E5FDF7 /* LaunchScreen.storyboard in Resources */,
935BD6CE1CE26EB600E5FDF7 /* Main.storyboard in Resources */,
935BD6E41CE26F0B00E5FDF7 /* Pattern1.storyboard in Resources */,
935BD6E61CE26F0B00E5FDF7 /* Pattern2.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -227,11 +243,11 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
935BD6C91CE26EB600E5FDF7 /* AppDelegate.swift in Sources */,
935BD6E11CE26F0B00E5FDF7 /* ImageCollectionViewCell.swift in Sources */,
935BD6E31CE26F0B00E5FDF7 /* MainViewController.swift in Sources */,
935BD6E51CE26F0B00E5FDF7 /* Pattern1ViewController.swift in Sources */,
935BD6E11CE26F0B00E5FDF7 /* ImageCollectionViewCell.swift in Sources */,
935BD6E71CE26F0B00E5FDF7 /* Pattern2ViewController.swift in Sources */,
935BD6C91CE26EB600E5FDF7 /* AppDelegate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -12,7 +12,7 @@ final class ImageCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var imageView: UIImageView!
static let identifier = "ImageCollectionViewCell"
static let nib = UINib(nibName: "ImageCollectionViewCell", bundle: nil)
func configure(_ indexPath: IndexPath) {
func configure(indexPath: IndexPath) {
let image = UIImage(named: String(indexPath.item))
imageView.image = image
setNeedsLayout()
+31 -11
View File
@@ -10,39 +10,59 @@ import UIKit
import InfiniteCollectionView
final class MainViewController: UIViewController {
var patterns = ["pattern1", "pattern2"]
let identifier = "tableViewCell"
enum Pattern: Int, CustomStringConvertible {
case pattern1
case pattern2
static var count: Int { return 2 }
var description: String {
switch self {
case .pattern1: return "pattern1"
case .pattern2: return "pattern2"
}
}
}
fileprivate let identifier = "tableViewCell"
fileprivate var cellHeight: CGFloat {
return (UIScreen.main.bounds.height - 64) / CGFloat(Pattern.count)
}
@IBOutlet weak var tableView: UITableView! {
didSet {
tableView.delegate = self
tableView.dataSource = self
tableView.rowHeight = cellHeight
tableView.estimatedRowHeight = cellHeight
tableView.separatorInset = .zero
tableView.layoutMargins = .zero
tableView.register(UITableViewCell.self, forCellReuseIdentifier: identifier)
tableView.rowHeight = 100
tableView.estimatedRowHeight = 100
}
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if let selectedIndexPath = tableView.indexPathForSelectedRow {
tableView.deselectRow(at: selectedIndexPath, animated: true)
}
guard let selectedIndexPath = tableView.indexPathForSelectedRow else { return }
tableView.deselectRow(at: selectedIndexPath, animated: true)
}
}
// MARK: - UITableViewDelegate, UITableViewDataSource
extension MainViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return patterns.count
return Pattern.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: identifier)!
cell.textLabel?.text = patterns[indexPath.row]
let pattern = Pattern(rawValue: indexPath.row)
cell.textLabel?.text = pattern?.description
cell.textLabel?.textAlignment = .center
cell.textLabel?.font = UIFont.boldSystemFont(ofSize: 24)
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if indexPath.row == 0 {
guard let pattern = Pattern(rawValue: indexPath.row) else { return }
switch pattern {
case .pattern1:
let controller = Pattern1ViewController.createFromStoryboard()
navigationController?.pushViewController(controller, animated: true)
} else if indexPath.row == 1 {
case .pattern2:
let controller = Pattern2ViewController.createFromStoryboard()
navigationController?.pushViewController(controller, animated: true)
}
+2 -2
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="11535.1" systemVersion="16A323" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="jtB-7l-rQl">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11542" systemVersion="16B2555" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="jtB-7l-rQl">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11523"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11524"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
+14 -9
View File
@@ -10,12 +10,11 @@ import UIKit
import InfiniteCollectionView
final class Pattern1ViewController: UIViewController {
var items = ["1", "2", "3", "4"]
var itemsCount: Int = 5
@IBOutlet weak var collectionView: InfiniteCollectionView! {
didSet {
collectionView.infiniteDataSource = self
collectionView.infiniteDelegate = self
collectionView.cellWidth = UIScreen.main.bounds.width
collectionView.register(ImageCollectionViewCell.nib, forCellWithReuseIdentifier: ImageCollectionViewCell.identifier)
}
}
@@ -26,18 +25,24 @@ final class Pattern1ViewController: UIViewController {
}
@IBOutlet weak var pageControl: UIPageControl! {
didSet {
pageControl.numberOfPages = items.count
pageControl.numberOfPages = itemsCount
}
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
NotificationCenter.default.addObserver(self, selector: #selector(Pattern1ViewController.rotate(_:)), name: .UIDeviceOrientationDidChange, object: nil)
}
deinit {
NotificationCenter.default.removeObserver(self, name: .UIDeviceOrientationDidChange, object: nil)
}
static func createFromStoryboard() -> Pattern1ViewController {
let storyboard = UIStoryboard(name: "Pattern1", bundle: nil)
return storyboard.instantiateInitialViewController() as! Pattern1ViewController
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
layout.itemSize = size
func rotate(_ notification: Notification) {
layout.itemSize = UIScreen.main.bounds.size
layout.invalidateLayout()
collectionView.cellWidth = size.width
collectionView.rotate(notification)
collectionView.layoutIfNeeded()
collectionView.setNeedsLayout()
}
@@ -46,11 +51,11 @@ final class Pattern1ViewController: UIViewController {
// MARK: - InfiniteCollectionViewDataSource, InfiniteCollectionViewDelegate
extension Pattern1ViewController: InfiniteCollectionViewDataSource, InfiniteCollectionViewDelegate {
func number(ofItems collectionView: UICollectionView) -> Int {
return items.count
return itemsCount
}
func collectionView(_ collectionView: UICollectionView, dequeueForItemAt dequeueIndexPath: IndexPath, cellForItemAt usableIndexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: ImageCollectionViewCell.identifier, for: dequeueIndexPath) as! ImageCollectionViewCell
cell.configure(usableIndexPath)
cell.configure(indexPath: usableIndexPath)
return cell
}
func infiniteCollectionView(_ collectionView: UICollectionView, didSelectItemAt usableIndexPath: IndexPath) {
+17 -17
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="11535.1" systemVersion="16A323" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="OWH-Uo-QHx">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11542" systemVersion="16B2555" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="OWH-Uo-QHx">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11523"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11524"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
@@ -25,15 +25,15 @@
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="InfiniteTableViewCell" rowHeight="161" id="1U1-fg-z8H" customClass="InfiniteTableViewCell" customModule="Example" customModuleProvider="target">
<rect key="frame" x="0.0" y="28" width="375" height="161"/>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="InfiniteTableViewCell" rowHeight="240" id="1U1-fg-z8H" customClass="InfiniteTableViewCell" customModule="Example" customModuleProvider="target">
<rect key="frame" x="0.0" y="28" width="375" height="240"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="1U1-fg-z8H" id="FjB-bh-baH">
<rect key="frame" x="0.0" y="0.0" width="375" height="160.5"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="239"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" pagingEnabled="YES" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="g4o-O8-u5y" customClass="InfiniteCollectionView" customModule="InfiniteCollectionView">
<rect key="frame" x="0.0" y="0.0" width="375" height="160.5"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="240"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
<collectionViewFlowLayout key="collectionViewLayout" scrollDirection="horizontal" minimumLineSpacing="0.0" minimumInteritemSpacing="0.0" id="JvE-3O-3Xs">
<size key="itemSize" width="50" height="50"/>
@@ -43,14 +43,14 @@
</collectionViewFlowLayout>
<cells>
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" reuseIdentifier="ImageCollectionViewCell" id="PWv-9R-TGh" customClass="ImageCollectionViewCell" customModule="Example" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.5" width="375" height="160"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="240"/>
<autoresizingMask key="autoresizingMask"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
<rect key="frame" x="0.0" y="0.0" width="375" height="160"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="240"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="m9D-ne-YCP">
<rect key="frame" x="0.0" y="0.0" width="375" height="160"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="240"/>
</imageView>
</subviews>
</view>
@@ -60,7 +60,7 @@
<constraint firstItem="m9D-ne-YCP" firstAttribute="leading" secondItem="PWv-9R-TGh" secondAttribute="leading" id="kKT-hw-BrG"/>
<constraint firstAttribute="bottom" secondItem="m9D-ne-YCP" secondAttribute="bottom" id="lvQ-hr-UgB"/>
</constraints>
<size key="customSize" width="375" height="160"/>
<size key="customSize" width="375" height="240"/>
<connections>
<outlet property="imageView" destination="m9D-ne-YCP" id="c9f-Gz-ruC"/>
</connections>
@@ -68,14 +68,14 @@
</cells>
</collectionView>
<view userInteractionEnabled="NO" alpha="0.5" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="cWs-n0-Daa">
<rect key="frame" x="0.0" y="103.5" width="375" height="37"/>
<rect key="frame" x="0.0" y="182.5" width="375" height="37"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="height" constant="37" id="Jfa-Ja-OcD"/>
</constraints>
</view>
<pageControl opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" numberOfPages="3" translatesAutoresizingMaskIntoConstraints="NO" id="TnJ-eK-8qD">
<rect key="frame" x="0.0" y="103.5" width="375" height="37"/>
<rect key="frame" x="0.0" y="182.5" width="375" height="37"/>
<constraints>
<constraint firstAttribute="height" constant="37" id="iLI-sf-nVD"/>
</constraints>
@@ -102,15 +102,15 @@
<outlet property="pageControl" destination="TnJ-eK-8qD" id="APk-sp-T8S"/>
</connections>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="Infinite2TableViewCell" rowHeight="101" id="Pbe-Q2-B3O" customClass="Infinite2TableViewCell" customModule="Example" customModuleProvider="target">
<rect key="frame" x="0.0" y="189" width="375" height="101"/>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="Infinite2TableViewCell" rowHeight="120" id="Pbe-Q2-B3O" customClass="Infinite2TableViewCell" customModule="Example" customModuleProvider="target">
<rect key="frame" x="0.0" y="268" width="375" height="120"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Pbe-Q2-B3O" id="Vro-Kf-tWq">
<rect key="frame" x="0.0" y="0.0" width="375" height="100.5"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="119"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="ba3-za-Kdk" customClass="InfiniteCollectionView" customModule="InfiniteCollectionView">
<rect key="frame" x="0.0" y="0.0" width="375" height="100.5"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="119.5"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
<collectionViewFlowLayout key="collectionViewLayout" scrollDirection="horizontal" minimumLineSpacing="10" minimumInteritemSpacing="10" id="9h8-PU-jeW">
<size key="itemSize" width="100" height="100"/>
@@ -120,7 +120,7 @@
</collectionViewFlowLayout>
<cells>
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" reuseIdentifier="ImageCollectionViewCell" id="HBK-Vd-0rJ" customClass="ImageCollectionViewCell" customModule="Example" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.5" width="100" height="100"/>
<rect key="frame" x="0.0" y="10" width="100" height="100"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
<rect key="frame" x="0.0" y="0.0" width="100" height="100"/>
+22 -25
View File
@@ -10,12 +10,10 @@ import UIKit
import InfiniteCollectionView
final class Pattern2ViewController: UIViewController {
static func createFromStoryboard() -> Pattern2ViewController {
let storyboard = UIStoryboard(name: "Pattern2", bundle: nil)
return storyboard.instantiateInitialViewController() as! Pattern2ViewController
}
@IBOutlet weak var tableView: UITableView! {
didSet {
tableView.delegate = self
@@ -25,38 +23,35 @@ final class Pattern2ViewController: UIViewController {
}
}
// MARK: - UITableViewDataSource, UITableViewDelegate
extension Pattern2ViewController: UITableViewDataSource, UITableViewDelegate {
func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 {
return 1
} else if section == 1 {
return 1
switch section {
case 0, 1: return 1
default: return 0
}
return 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == 0 {
switch indexPath.section {
case 0:
let cell = tableView.dequeueReusableCell(withIdentifier: InfiniteTableViewCell.identifier) as! InfiniteTableViewCell
return cell
} else if indexPath.section == 1 {
case 1:
let cell = tableView.dequeueReusableCell(withIdentifier: Infinite2TableViewCell.identifier) as! Infinite2TableViewCell
return cell
} else {
default:
return UITableViewCell()
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath.section == 0 {
return 240
} else if indexPath.section == 1 {
return 120
switch indexPath.section {
case 0: return 240
case 1: return 120
default: return 0
}
return 0
}
}
@@ -64,16 +59,15 @@ final class InfiniteTableViewCell: UITableViewCell {
static let identifier = "InfiniteTableViewCell"
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
NotificationCenter.default.addObserver(self, selector: #selector(InfiniteTableViewCell.rotate(_:)), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(InfiniteTableViewCell.rotate(_:)), name: .UIDeviceOrientationDidChange, object: nil)
}
deinit {
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
NotificationCenter.default.removeObserver(self, name: .UIDeviceOrientationDidChange, object: nil)
}
@IBOutlet weak var collectionView: InfiniteCollectionView! {
didSet {
collectionView.infiniteDataSource = self
collectionView.infiniteDelegate = self
collectionView.cellWidth = UIScreen.main.bounds.width
collectionView.register(ImageCollectionViewCell.nib, forCellWithReuseIdentifier: ImageCollectionViewCell.identifier)
}
}
@@ -91,7 +85,7 @@ final class InfiniteTableViewCell: UITableViewCell {
let size = CGSize(width: UIScreen.main.bounds.width, height: 239)
layout.itemSize = size
layout.invalidateLayout()
collectionView.cellWidth = size.width
collectionView.rotate(notification)
collectionView.layoutIfNeeded()
collectionView.setNeedsLayout()
}
@@ -104,7 +98,7 @@ extension InfiniteTableViewCell: InfiniteCollectionViewDataSource, InfiniteColle
}
func collectionView(_ collectionView: UICollectionView, dequeueForItemAt dequeueIndexPath: IndexPath, cellForItemAt usableIndexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: ImageCollectionViewCell.identifier, for: dequeueIndexPath) as! ImageCollectionViewCell
cell.configure(usableIndexPath)
cell.configure(indexPath: usableIndexPath)
return cell
}
func scrollView(_ scrollView: UIScrollView, pageIndex: Int) {
@@ -116,16 +110,15 @@ final class Infinite2TableViewCell: UITableViewCell {
static let identifier = "Infinite2TableViewCell"
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
NotificationCenter.default.addObserver(self, selector: #selector(Infinite2TableViewCell.rotate(_:)), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(Infinite2TableViewCell.rotate(_:)), name: .UIDeviceOrientationDidChange, object: nil)
}
deinit {
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
NotificationCenter.default.removeObserver(self, name: .UIDeviceOrientationDidChange, object: nil)
}
@IBOutlet weak var collectionView: InfiniteCollectionView! {
didSet {
collectionView.infiniteDataSource = self
collectionView.infiniteDelegate = self
collectionView.cellWidth = 100
collectionView.register(ImageCollectionViewCell.nib, forCellWithReuseIdentifier: ImageCollectionViewCell.identifier)
}
}
@@ -138,12 +131,16 @@ extension Infinite2TableViewCell: InfiniteCollectionViewDataSource, InfiniteColl
}
func collectionView(_ collectionView: UICollectionView, dequeueForItemAt dequeueIndexPath: IndexPath, cellForItemAt usableIndexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: ImageCollectionViewCell.identifier, for: dequeueIndexPath) as! ImageCollectionViewCell
cell.configure(usableIndexPath)
cell.configure(indexPath: usableIndexPath)
return cell
}
func infiniteCollectionView(_ collectionView: UICollectionView, didSelectItemAt usableIndexPath: IndexPath) {
print("didSelectItemAt: \(usableIndexPath.item)")
}
func rotate(_ notification: Notification) {
collectionView.collectionViewLayout.invalidateLayout()
collectionView.rotate(notification)
collectionView.layoutIfNeeded()
collectionView.setNeedsLayout()
}
}
+2 -2
View File
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "InfiniteCollectionView"
s.version = "1.1.0"
s.version = "1.3.1"
s.summary = "Infinite Scrolling Using UICollectionView."
s.homepage = "https://github.com/hryk224/InfiniteCollectionView"
s.screenshots = "https://github.com/hryk224/InfiniteCollectionView/wiki/images/sample1.gif"
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
s.author = { "hyyk224" => "hryk224@gmail.com" }
s.platform = :ios, "8.0"
s.source = { :git => "https://github.com/hryk224/InfiniteCollectionView.git", :tag => "#{s.version}" }
s.source_files = "InfiniteCollectionView/*.{h,swift}"
s.source_files = "Sources/*.{h,swift}"
s.frameworks = "UIKit"
s.requires_arc = true
end
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>
@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.1.0</string>
<string>1.3.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
+109 -184
View File
@@ -7,21 +7,20 @@
objects = {
/* Begin PBXBuildFile section */
935BD7281CE2702D00E5FDF7 /* InfiniteCollectionView.h in Headers */ = {isa = PBXBuildFile; fileRef = 935BD7261CE2702D00E5FDF7 /* InfiniteCollectionView.h */; settings = {ATTRIBUTES = (Public, ); }; };
935BD7291CE2702D00E5FDF7 /* InfiniteCollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 935BD7271CE2702D00E5FDF7 /* InfiniteCollectionView.swift */; };
OBJ_22 /* InfiniteCollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_9 /* InfiniteCollectionView.swift */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
935BD7001CE26F3B00E5FDF7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
935BD70D1CE26F8E00E5FDF7 /* InfiniteCollectionView.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = InfiniteCollectionView.framework; sourceTree = BUILT_PRODUCTS_DIR; };
935BD7261CE2702D00E5FDF7 /* InfiniteCollectionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InfiniteCollectionView.h; sourceTree = "<group>"; };
935BD7271CE2702D00E5FDF7 /* InfiniteCollectionView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InfiniteCollectionView.swift; sourceTree = "<group>"; };
93CB2E361E563B85000DC0C1 /* InfiniteCollectionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InfiniteCollectionView.h; sourceTree = "<group>"; };
OBJ_15 /* InfiniteCollectionView.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = InfiniteCollectionView.framework; sourceTree = BUILT_PRODUCTS_DIR; };
OBJ_6 /* Package.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; path = Package.swift; sourceTree = "<group>"; };
OBJ_9 /* InfiniteCollectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfiniteCollectionView.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
935BD7091CE26F8E00E5FDF7 /* Frameworks */ = {
OBJ_23 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
buildActionMask = 0;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
@@ -29,54 +28,50 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
935BD6E81CE26F3B00E5FDF7 = {
OBJ_14 /* Products */ = {
isa = PBXGroup;
children = (
935BD6F31CE26F3B00E5FDF7 /* InfiniteCollectionView */,
935BD6F21CE26F3B00E5FDF7 /* Products */,
);
sourceTree = "<group>";
};
935BD6F21CE26F3B00E5FDF7 /* Products */ = {
isa = PBXGroup;
children = (
935BD70D1CE26F8E00E5FDF7 /* InfiniteCollectionView.framework */,
OBJ_15 /* InfiniteCollectionView.framework */,
);
name = Products;
sourceTree = "<group>";
sourceTree = BUILT_PRODUCTS_DIR;
};
935BD6F31CE26F3B00E5FDF7 /* InfiniteCollectionView */ = {
OBJ_5 = {
isa = PBXGroup;
children = (
935BD7261CE2702D00E5FDF7 /* InfiniteCollectionView.h */,
935BD7271CE2702D00E5FDF7 /* InfiniteCollectionView.swift */,
935BD7001CE26F3B00E5FDF7 /* Info.plist */,
OBJ_6 /* Package.swift */,
OBJ_7 /* Sources */,
OBJ_14 /* Products */,
);
path = InfiniteCollectionView;
sourceTree = "<group>";
};
OBJ_7 /* Sources */ = {
isa = PBXGroup;
children = (
OBJ_8 /* InfiniteCollectionView */,
);
path = Sources;
sourceTree = "<group>";
};
OBJ_8 /* InfiniteCollectionView */ = {
isa = PBXGroup;
children = (
OBJ_9 /* InfiniteCollectionView.swift */,
93CB2E361E563B85000DC0C1 /* InfiniteCollectionView.h */,
);
name = InfiniteCollectionView;
path = Sources;
sourceTree = SOURCE_ROOT;
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
935BD70A1CE26F8E00E5FDF7 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
935BD7281CE2702D00E5FDF7 /* InfiniteCollectionView.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
935BD70C1CE26F8E00E5FDF7 /* InfiniteCollectionView */ = {
OBJ_17 /* InfiniteCollectionView */ = {
isa = PBXNativeTarget;
buildConfigurationList = 935BD7121CE26F8E00E5FDF7 /* Build configuration list for PBXNativeTarget "InfiniteCollectionView" */;
buildConfigurationList = OBJ_18 /* Build configuration list for PBXNativeTarget "InfiniteCollectionView" */;
buildPhases = (
935BD7081CE26F8E00E5FDF7 /* Sources */,
935BD7091CE26F8E00E5FDF7 /* Frameworks */,
935BD70A1CE26F8E00E5FDF7 /* Headers */,
935BD70B1CE26F8E00E5FDF7 /* Resources */,
OBJ_21 /* Sources */,
OBJ_23 /* Frameworks */,
);
buildRules = (
);
@@ -84,222 +79,152 @@
);
name = InfiniteCollectionView;
productName = InfiniteCollectionView;
productReference = 935BD70D1CE26F8E00E5FDF7 /* InfiniteCollectionView.framework */;
productReference = OBJ_15 /* InfiniteCollectionView.framework */;
productType = "com.apple.product-type.framework";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
935BD6E91CE26F3B00E5FDF7 /* Project object */ = {
OBJ_1 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0730;
LastUpgradeCheck = 0800;
ORGANIZATIONNAME = "hiroyuki yoshida";
TargetAttributes = {
935BD70C1CE26F8E00E5FDF7 = {
CreatedOnToolsVersion = 7.3.1;
LastSwiftMigration = 0800;
};
};
LastUpgradeCheck = 9999;
};
buildConfigurationList = 935BD6EC1CE26F3B00E5FDF7 /* Build configuration list for PBXProject "InfiniteCollectionView" */;
buildConfigurationList = OBJ_2 /* Build configuration list for PBXProject "InfiniteCollectionView" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 935BD6E81CE26F3B00E5FDF7;
productRefGroup = 935BD6F21CE26F3B00E5FDF7 /* Products */;
mainGroup = OBJ_5;
productRefGroup = OBJ_14 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
935BD70C1CE26F8E00E5FDF7 /* InfiniteCollectionView */,
OBJ_17 /* InfiniteCollectionView */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
935BD70B1CE26F8E00E5FDF7 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
935BD7081CE26F8E00E5FDF7 /* Sources */ = {
OBJ_21 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
buildActionMask = 0;
files = (
935BD7291CE2702D00E5FDF7 /* InfiniteCollectionView.swift in Sources */,
OBJ_22 /* InfiniteCollectionView.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
935BD7011CE26F3B00E5FDF7 /* Debug */ = {
OBJ_19 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PLATFORM_DIR)/Developer/Library/Frameworks",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
HEADER_SEARCH_PATHS = "$(inherited)";
INFOPLIST_FILE = InfiniteCollectionView.xcodeproj/InfiniteCollectionView_Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(TOOLCHAIN_DIR)/usr/lib/swift/macosx";
OTHER_LDFLAGS = "$(inherited)";
OTHER_SWIFT_FLAGS = "$(inherited)";
PRODUCT_BUNDLE_IDENTIFIER = InfiniteCollectionView;
PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)";
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
TARGET_NAME = InfiniteCollectionView;
};
name = Debug;
};
935BD7021CE26F3B00E5FDF7 /* Release */ = {
OBJ_20 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
VALIDATE_PRODUCT = YES;
ENABLE_TESTABILITY = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PLATFORM_DIR)/Developer/Library/Frameworks",
);
HEADER_SEARCH_PATHS = "$(inherited)";
INFOPLIST_FILE = InfiniteCollectionView.xcodeproj/InfiniteCollectionView_Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(TOOLCHAIN_DIR)/usr/lib/swift/macosx";
OTHER_LDFLAGS = "$(inherited)";
OTHER_SWIFT_FLAGS = "$(inherited)";
PRODUCT_BUNDLE_IDENTIFIER = InfiniteCollectionView;
PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)";
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
TARGET_NAME = InfiniteCollectionView;
};
name = Release;
};
935BD7131CE26F8E00E5FDF7 /* Debug */ = {
OBJ_3 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
COMBINE_HIDPI_IMAGES = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = InfiniteCollectionView/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = io.github.hryk224.InfiniteCollectionView;
ENABLE_NS_ASSERTIONS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MACOSX_DEPLOYMENT_TARGET = 10.10;
ONLY_ACTIVE_ARCH = YES;
OTHER_SWIFT_FLAGS = "-DXcode";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = "iphonesimulator iphoneos";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = SWIFT_PACKAGE;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
USE_HEADERMAP = NO;
};
name = Debug;
};
935BD7141CE26F8E00E5FDF7 /* Release */ = {
OBJ_4 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
COMBINE_HIDPI_IMAGES = YES;
COPY_PHASE_STRIP = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = InfiniteCollectionView/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = io.github.hryk224.InfiniteCollectionView;
GCC_OPTIMIZATION_LEVEL = s;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MACOSX_DEPLOYMENT_TARGET = 10.10;
OTHER_SWIFT_FLAGS = "-DXcode";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = "iphonesimulator iphoneos";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = SWIFT_PACKAGE;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_VERSION = 3.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
USE_HEADERMAP = NO;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
935BD6EC1CE26F3B00E5FDF7 /* Build configuration list for PBXProject "InfiniteCollectionView" */ = {
OBJ_18 /* Build configuration list for PBXNativeTarget "InfiniteCollectionView" */ = {
isa = XCConfigurationList;
buildConfigurations = (
935BD7011CE26F3B00E5FDF7 /* Debug */,
935BD7021CE26F3B00E5FDF7 /* Release */,
OBJ_19 /* Debug */,
OBJ_20 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
defaultConfigurationName = Debug;
};
935BD7121CE26F8E00E5FDF7 /* Build configuration list for PBXNativeTarget "InfiniteCollectionView" */ = {
OBJ_2 /* Build configuration list for PBXProject "InfiniteCollectionView" */ = {
isa = XCConfigurationList;
buildConfigurations = (
935BD7131CE26F8E00E5FDF7 /* Debug */,
935BD7141CE26F8E00E5FDF7 /* Release */,
OBJ_3 /* Debug */,
OBJ_4 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
defaultConfigurationName = Debug;
};
/* End XCConfigurationList section */
};
rootObject = 935BD6E91CE26F3B00E5FDF7 /* Project object */;
rootObject = OBJ_1 /* Project object */;
}
@@ -2,6 +2,6 @@
<Workspace
version = "1.0">
<FileRef
location = "self:InfiniteCollectionView.xcodeproj">
location = "self:">
</FileRef>
</Workspace>
@@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "9999"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "OBJ_17"
BuildableName = "InfiniteCollectionView.framework"
BlueprintName = "InfiniteCollectionView"
ReferencedContainer = "container:InfiniteCollectionView.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "OBJ_24"
BuildableName = "InfiniteCollectionViewTests.xctest"
BlueprintName = "InfiniteCollectionViewTests"
ReferencedContainer = "container:InfiniteCollectionView.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "OBJ_17"
BuildableName = "InfiniteCollectionView.framework"
BlueprintName = "InfiniteCollectionView"
ReferencedContainer = "container:InfiniteCollectionView.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>InfiniteCollectionView.xcscheme</key>
<dict></dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict></dict>
</dict>
</plist>
+9
View File
@@ -0,0 +1,9 @@
import PackageDescription
let package = Package(
name: "InfiniteCollectionView",
targets: [],
dependencies: [
.Package(url: "https://github.com/hryk224/InfiniteCollectionView", majorVersion: 1),
]
)
+1 -1
View File
@@ -6,6 +6,7 @@ Infinite horizontal scrolling using `UICollectionView`
[![Swift 3.0](https://img.shields.io/badge/Swift-3.0-orange.svg?style=flat)](https://developer.apple.com/swift/)
<img src="https://github.com/hryk224/InfiniteCollectionView/wiki/images/sample1.gif" width="320" >
<img src="https://github.com/hryk224/InfiniteCollectionView/wiki/images/sample2.gif" width="320" >
## Requirements
@@ -43,7 +44,6 @@ import InfiniteCollectionView
```Swift
collectionView.infiniteDataSource = XXX
collectionView.infiniteDelegate = XXX
collectionView.cellWidth = XXX
```
```Swift
@@ -27,19 +27,13 @@ import UIKit
}
open class InfiniteCollectionView: UICollectionView {
fileprivate typealias Me = InfiniteCollectionView
fileprivate static let dummyCount: Int = 3
fileprivate static let defaultIdentifier = "Cell"
open weak var infiniteDataSource: InfiniteCollectionViewDataSource?
open weak var infiniteDelegate: InfiniteCollectionViewDelegate?
open var cellWidth: CGFloat = UIScreen.main.bounds.width {
didSet {
contentWidth = totalContentWidth
setContentOffset(CGPoint(x: CGFloat(pageIndex + indexOffset) * cellWidth, y: contentOffset.y), animated: false)
}
}
@available(*, deprecated, message: "It becomes unnecessary because it uses UICollectionViewFlowLayout.")
open var cellWidth: CGFloat?
fileprivate let dummyCount: Int = 3
fileprivate let defaultIdentifier = "Cell"
fileprivate var indexOffset: Int = 0
fileprivate var contentWidth: CGFloat = 0
fileprivate var pageIndex = 0
required public init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
@@ -52,41 +46,61 @@ open class InfiniteCollectionView: UICollectionView {
deinit {
NotificationCenter.default.removeObserver(self, name: .UIDeviceOrientationDidChange, object: nil)
}
open override func reloadData() {
super.reloadData()
contentWidth = totalContentWidth
open func rotate(_ notification: Notification) {
setContentOffset(CGPoint(x: CGFloat(pageIndex + indexOffset) * itemWidth, y: contentOffset.y), animated: false)
}
func rotate(_ notification: Notification) {
contentWidth = totalContentWidth
open override func selectItem(at indexPath: IndexPath?, animated: Bool, scrollPosition: UICollectionViewScrollPosition) {
guard let indexPath = indexPath else { return }
// Correct the input IndexPath
let correctedIndexPath = IndexPath(row: correctedIndex(indexPath.item + indexOffset), section: 0)
// Get the currently visible cell(s) - assumes a cell is visible
guard let visibleCell = self.visibleCells.first else {
return
}
// Index path of the cell - does not consider multiple cells on the screen at the same time
guard let visibleIndexPath = self.indexPath(for: visibleCell) else {
return
}
let testIndexPath = IndexPath(row: correctedIndex(visibleIndexPath.item), section: 0)
guard correctedIndexPath != testIndexPath else {
return // Do not re-select the same cell
}
// Call supercase to select the correct IndexPath
super.selectItem(at: correctedIndexPath, animated: animated, scrollPosition: scrollPosition)
}
}
// MARK: - private
private extension InfiniteCollectionView {
var itemWidth: CGFloat {
guard let layout = collectionViewLayout as? UICollectionViewFlowLayout else { return 0 }
return layout.itemSize.width + layout.minimumInteritemSpacing
}
var totalContentWidth: CGFloat {
let numberOfCells = infiniteDataSource?.number(ofItems: self) ?? 0
return CGFloat(numberOfCells) * cellWidth
let numberOfCells: CGFloat = CGFloat(infiniteDataSource?.number(ofItems: self) ?? 0)
return numberOfCells * itemWidth
}
func configure() {
delegate = self
dataSource = self
register(UICollectionViewCell.self, forCellWithReuseIdentifier: Me.defaultIdentifier)
register(UICollectionViewCell.self, forCellWithReuseIdentifier: defaultIdentifier)
NotificationCenter.default.addObserver(self, selector: #selector(InfiniteCollectionView.rotate(_:)), name: .UIDeviceOrientationDidChange, object: nil)
}
func centerIfNeeded(_ scrollView: UIScrollView) {
let currentOffset = contentOffset
let centerX = (CGFloat(Me.dummyCount) * contentWidth - bounds.width) / 2
let centerX = (scrollView.contentSize.width - bounds.width) / 2
let distFromCenter = centerX - currentOffset.x
if fabs(distFromCenter) > (contentWidth / 4) {
let cellcount = distFromCenter / cellWidth
if fabs(distFromCenter) > (totalContentWidth / 4) {
let cellcount = distFromCenter / itemWidth
let shiftCells = Int((cellcount > 0) ? floor(cellcount) : ceil(cellcount))
let offsetCorrection = (abs(cellcount).truncatingRemainder(dividingBy: 1)) * cellWidth
let offsetCorrection = (abs(cellcount).truncatingRemainder(dividingBy: 1)) * itemWidth
if centerX > contentOffset.x {
contentOffset = CGPoint(x: centerX - offsetCorrection, y: currentOffset.y)
} else {
contentOffset = CGPoint(x: centerX + offsetCorrection, y: currentOffset.y)
}
shiftContentArray(correctedIndex(shiftCells))
let offset = correctedIndex(shiftCells)
indexOffset += offset
reloadData()
}
let centerPoint = CGPoint(x: scrollView.frame.size.width / 2 + scrollView.contentOffset.x, y: scrollView.frame.size.height / 2 + scrollView.contentOffset.y)
@@ -94,9 +108,6 @@ private extension InfiniteCollectionView {
pageIndex = correctedIndex(indexPath.item - indexOffset)
infiniteDelegate?.scrollView?(scrollView, pageIndex: pageIndex)
}
func shiftContentArray(_ offset: Int) {
indexOffset += offset
}
func correctedIndex(_ indexToCorrect: Int) -> Int {
guard let numberOfItems = infiniteDataSource?.number(ofItems: self) else { return 0 }
if numberOfItems > indexToCorrect && indexToCorrect >= 0 {
@@ -113,13 +124,13 @@ private extension InfiniteCollectionView {
extension InfiniteCollectionView: UICollectionViewDataSource {
public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
let numberOfItems = infiniteDataSource?.number(ofItems: collectionView) ?? 0
return Me.dummyCount * numberOfItems
return dummyCount * numberOfItems
}
public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if let maybeCell = infiniteDataSource?.collectionView(collectionView, dequeueForItemAt: indexPath, cellForItemAt: IndexPath(item: correctedIndex(indexPath.item - indexOffset), section: 0)) {
return maybeCell
guard let cell = infiniteDataSource?.collectionView(collectionView, dequeueForItemAt: indexPath, cellForItemAt: IndexPath(item: correctedIndex(indexPath.item - indexOffset), section: 0)) else {
return collectionView.dequeueReusableCell(withReuseIdentifier: defaultIdentifier, for: indexPath)
}
return collectionView.dequeueReusableCell(withReuseIdentifier: Me.defaultIdentifier, for: indexPath)
return cell
}
}