Compare commits

...

13 Commits

Author SHA1 Message Date
Arnaud Dorgans e4378462e2 fix 2018-01-05 17:27:50 +01:00
Arnaud Dorgans a8b2962c9b fix 2018-01-05 17:25:49 +01:00
Arnaud Dorgans 31f9b56b3a fix 2018-01-05 17:24:45 +01:00
Arnaud Dorgans 51473be4c7 fix readme 2018-01-05 17:21:19 +01:00
Arnaud Dorgans ee26e28d39 spec gif update 2018-01-05 16:44:49 +01:00
Arnaud Dorgans f6b339ad96 horizontal fix 2018-01-05 16:42:36 +01:00
Arnaud Dorgans cc916ccd92 gif 2018-01-05 15:55:00 +01:00
Arnaud Dorgans ae1969e26f Update README.md 2018-01-05 15:17:34 +01:00
Arnaud Dorgans 42e8d150a2 vertical gif 2018-01-05 15:13:27 +01:00
Arnaud Dorgans b839a5af47 gif 2018-01-05 14:49:06 +01:00
Arnaud Dorgans a522cf0c36 thread fix 2018-01-04 17:42:22 +01:00
Arnaud Dorgans 294fd763f8 storyboard update 2018-01-04 15:51:40 +01:00
Arnaud Dorgans 9468de35bd thread fix 2018-01-04 15:30:13 +01:00
14 changed files with 79 additions and 38 deletions
@@ -597,6 +597,7 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.0;
TARGETED_DEVICE_FAMILY = 1;
};
name = Debug;
};
@@ -613,6 +614,7 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.0;
TARGETED_DEVICE_FAMILY = 1;
};
name = Release;
};
@@ -15,8 +15,8 @@
<scene sceneID="l4I-9G-XdF">
<objects>
<navigationController id="yGQ-hH-2v6" sceneMemberID="viewController">
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="IdE-R7-9TG">
<rect key="frame" x="0.0" y="20" width="320" height="44"/>
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" largeTitles="YES" id="IdE-R7-9TG">
<rect key="frame" x="0.0" y="20" width="320" height="96"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<connections>
@@ -98,14 +98,18 @@
<segue destination="ctO-Ld-yhL" kind="show" id="qss-AL-dgi"/>
</connections>
</tableViewCell>
</cells>
</tableViewSection>
<tableViewSection headerTitle="Delegate" id="lpd-Xl-djA">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="c9c-gc-NDL" style="IBUITableViewCellStyleDefault" id="7Dq-og-5lN">
<rect key="frame" x="0.0" y="132" width="320" height="44"/>
<rect key="frame" x="0.0" y="160" width="320" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="7Dq-og-5lN" id="XGb-gg-zbn">
<rect key="frame" x="0.0" y="0.0" width="320" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Picker" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="c9c-gc-NDL">
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Horizontal Picker" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="c9c-gc-NDL">
<rect key="frame" x="16" y="0.0" width="288" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
@@ -123,7 +127,7 @@
<tableViewSection headerTitle="Rx" id="l6q-RG-uyY">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="i8W-08-UPB" style="IBUITableViewCellStyleDefault" id="1E8-fo-BBx">
<rect key="frame" x="0.0" y="204" width="320" height="44"/>
<rect key="frame" x="0.0" y="232" width="320" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="1E8-fo-BBx" id="NMq-kd-IrV">
<rect key="frame" x="0.0" y="0.0" width="320" height="43.5"/>
@@ -203,6 +207,9 @@
</cells>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isItemPagingEnabled" value="YES"/>
<userDefinedRuntimeAttribute type="number" keyPath="velocityMultiplier">
<real key="value" value="500"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
<connections>
<outlet property="dataSource" destination="ctO-Ld-yhL" id="bXu-Jz-K7t"/>
@@ -218,14 +225,14 @@
<constraint firstItem="enX-ef-ELn" firstAttribute="leading" secondItem="C5p-bu-Djh" secondAttribute="leading" id="uX4-ox-gnL"/>
</constraints>
</view>
<navigationItem key="navigationItem" title="Custom Layout" id="hZl-1w-5Nq"/>
<navigationItem key="navigationItem" title="Custom Layout" largeTitleDisplayMode="never" id="hZl-1w-5Nq"/>
<connections>
<outlet property="infiniteCollectionView" destination="enX-ef-ELn" id="jKo-DT-4uH"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="4s9-AY-FII" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-770" y="802"/>
<point key="canvasLocation" x="21" y="788"/>
</scene>
<!--Infinite Delegate-->
<scene sceneID="HqS-9O-oG4">
@@ -313,7 +320,7 @@
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="jlK-LR-KNy" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="22" y="802"/>
<point key="canvasLocation" x="784" y="-664"/>
</scene>
<!--Rx-->
<scene sceneID="w7X-Gq-cbX">
@@ -371,14 +378,14 @@
<constraint firstAttribute="bottom" secondItem="ci9-0n-fka" secondAttribute="bottom" id="yOo-Td-V0c"/>
</constraints>
</view>
<navigationItem key="navigationItem" title="Rx" id="BMY-0d-YCj"/>
<navigationItem key="navigationItem" title="Rx" largeTitleDisplayMode="never" id="BMY-0d-YCj"/>
<connections>
<outlet property="infiniteCollectionView" destination="ci9-0n-fka" id="fSY-Qh-bhA"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="TkU-4C-L7I" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-770" y="-671"/>
<point key="canvasLocation" x="784" y="60"/>
</scene>
<!--Horizontal Layout-->
<scene sceneID="0Xz-LA-moA">
@@ -396,7 +403,7 @@
</collectionViewFlowLayout>
<cells>
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" reuseIdentifier="cell" id="BVQ-cb-bj4" customClass="Cell" customModule="InfiniteLayout_Example" customModuleProvider="target">
<rect key="frame" x="0.0" y="177" width="250" height="150"/>
<rect key="frame" x="0.0" y="151" width="250" height="150"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO">
<rect key="frame" x="0.0" y="0.0" width="250" height="150"/>
@@ -421,9 +428,6 @@
</cells>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="isItemPagingEnabled" value="YES"/>
<userDefinedRuntimeAttribute type="number" keyPath="velocityMultiplier">
<real key="value" value="1"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
<connections>
<outlet property="dataSource" destination="CU7-Hg-6kG" id="BOZ-dL-WLG"/>
@@ -434,7 +438,7 @@
</collectionViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="Dsp-JP-Q6i" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="21" y="-670"/>
<point key="canvasLocation" x="21" y="-664"/>
</scene>
<!--Vertical Layout-->
<scene sceneID="ccn-9j-1sQ">
@@ -483,7 +487,7 @@
<outlet property="delegate" destination="9P2-Ud-D2M" id="ns0-fe-DSq"/>
</connections>
</collectionView>
<navigationItem key="navigationItem" title="Vertical Layout" id="2E2-oh-ELb"/>
<navigationItem key="navigationItem" title="Vertical Layout" largeTitleDisplayMode="never" id="2E2-oh-ELb"/>
</collectionViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="Lvb-qy-gZV" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
@@ -22,4 +22,8 @@ class BaseCollectionViewController: InfiniteCollectionViewController {
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 20
}
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
collectionView.scrollToItem(at: indexPath, at: self.infiniteCollectionView!.infiniteLayout.scrollDirection == .vertical ? .centeredVertically : .centeredHorizontally, animated: true)
}
}
@@ -17,11 +17,7 @@ class CustomViewController: UIViewController {
extension CustomViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 14
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 2
return 20
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
@@ -31,6 +27,13 @@ extension CustomViewController: UICollectionViewDataSource {
}
}
extension CustomViewController: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
collectionView.scrollToItem(at: indexPath, at: .centeredVertically, animated: true)
}
}
extension CustomViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
@@ -30,6 +30,13 @@ extension PickerController: UICollectionViewDataSource {
}
}
extension PickerController: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
collectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
}
}
extension PickerController: InfiniteCollectionViewDelegate {
func infiniteCollectionView(_ infiniteCollectionView: InfiniteCollectionView, didChangeCenteredIndexPath centeredIndexPath: IndexPath?) {
@@ -35,5 +35,11 @@ class RxBaseCollectionViewController: UIViewController {
}
print("centered: \(current + 1)")
}).disposed(by: disposeBag)
infiniteCollectionView.rx.itemSelected
.asDriver()
.drive(onNext: { [unowned self] indexPath in
self.infiniteCollectionView.scrollToItem(at: indexPath, at: .centeredVertically, animated: true)
}).disposed(by: disposeBag)
}
}
+2 -2
View File
@@ -8,7 +8,7 @@
Pod::Spec.new do |s|
s.name = 'InfiniteLayout'
s.version = '0.2.0.3'
s.version = '0.2.3'
s.summary = 'Horizontal and Vertical infinite scrolling feature for UICollectionView with Paging, NSProxy delegate, Reactive extension'
# This description is used to generate tags and improve search results.
@@ -22,7 +22,7 @@ Horizontal and Vertical infinite scrolling feature for UICollectionView with Pag
DESC
s.homepage = 'https://github.com/Arnoymous/InfiniteLayout'
# s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2'
s.screenshots = 'https://github.com/Arnoymous/InfiniteLayout/raw/master/horizontal.gif', 'https://github.com/Arnoymous/InfiniteLayout/raw/master/vertical.gif', 'https://github.com/Arnoymous/InfiniteLayout/raw/master/custom.gif', 'https://github.com/Arnoymous/InfiniteLayout/raw/master/delegate.gif'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'Arnoymous' => 'ineox@me.com' }
s.source = { :git => 'https://github.com/Arnoymous/InfiniteLayout.git', :tag => s.version.to_s }
@@ -112,8 +112,7 @@ open class InfiniteCollectionView: UICollectionView {
open override func layoutSubviews() {
super.layoutSubviews()
self.loopCollectionViewIfNeeded()
self.updateLayoutIfNeeded()
}
}
@@ -165,15 +164,9 @@ extension InfiniteCollectionView: UICollectionViewDataSource {
extension InfiniteCollectionView: UICollectionViewDelegate {
// MARK: Loop
func loopCollectionViewIfNeeded() {
self.infiniteLayout.loopCollectionViewIfNeeded()
self.centerCollectionViewIfNeeded()
}
public func scrollViewDidScroll(_ scrollView: UIScrollView) {
delegateProxy.delegate?.scrollViewDidScroll?(scrollView)
func updateLayoutIfNeeded() {
self.loopCollectionViewIfNeeded()
self.centerCollectionViewIfNeeded()
let preferredVisibleIndexPath = infiniteLayout.preferredVisibleLayoutAttributes()?.indexPath
if self.centeredIndexPath != preferredVisibleIndexPath {
@@ -182,6 +175,16 @@ extension InfiniteCollectionView: UICollectionViewDelegate {
}
}
// MARK: Loop
func loopCollectionViewIfNeeded() {
self.infiniteLayout.loopCollectionViewIfNeeded()
}
public func scrollViewDidScroll(_ scrollView: UIScrollView) {
delegateProxy.delegate?.scrollViewDidScroll?(scrollView)
self.updateLayoutIfNeeded()
}
// MARK: Paging
func centerCollectionViewIfNeeded() {
guard isItemPagingEnabled,
+11 -4
View File
@@ -11,7 +11,7 @@ open class InfiniteLayout: UICollectionViewFlowLayout {
public var velocityMultiplier: CGFloat = 1 // used to simulate paging
private let multiplier: CGFloat = 100 // contentOffset multiplier
private let multiplier: CGFloat = 500 // contentOffset multiplier
private var contentSize: CGSize = .zero
@@ -131,6 +131,13 @@ open class InfiniteLayout: UICollectionViewFlowLayout {
}
// MARK: Loop
private func updateContentOffset(_ offset: CGPoint) {
guard let collectionView = self.collectionView else {
return
}
collectionView.contentOffset = offset
collectionView.layoutIfNeeded()
}
private func preferredContentOffset(forContentOffset contentOffset: CGPoint) -> CGPoint {
return rect(from: CGRect(origin: contentOffset, size: .zero), page: self.page(from: .zero, offset: multiplier / 2)).origin
}
@@ -142,7 +149,7 @@ open class InfiniteLayout: UICollectionViewFlowLayout {
let page = self.pageIndex(from: self.page(for: collectionView.contentOffset))
let offset = self.preferredContentOffset(forContentOffset: collectionView.contentOffset)
if (page < 2 || page > self.multiplier - 2) && collectionView.contentOffset != offset {
collectionView.contentOffset = offset
self.updateContentOffset(offset)
}
}
@@ -244,11 +251,11 @@ open class InfiniteLayout: UICollectionViewFlowLayout {
return
}
guard let preferredAttributes = self.preferredVisibleLayoutAttributes(indexPath: indexPath),
let offset = self.centeredContentOffset(forRect: preferredAttributes.frame),
let offset = self.centeredContentOffset(forRect: preferredAttributes.frame),
collectionView.contentOffset != offset else {
return
}
collectionView.contentOffset = offset
self.updateContentOffset(offset)
}
// MARK: Copy
+6 -1
View File
@@ -5,6 +5,9 @@
[![License](https://img.shields.io/cocoapods/l/InfiniteLayout.svg?style=flat)](http://cocoapods.org/pods/InfiniteLayout)
[![Platform](https://img.shields.io/cocoapods/p/InfiniteLayout.svg?style=flat)](http://cocoapods.org/pods/InfiniteLayout)
<img src="https://github.com/Arnoymous/InfiniteLayout/raw/master/horizontal.gif" width="250" height="540"><img src="https://github.com/Arnoymous/InfiniteLayout/raw/master/vertical.gif" width="250" height="540"><img src="https://github.com/Arnoymous/InfiniteLayout/raw/master/custom.gif" width="250" height="540">
## Example
To run the example project, clone the repo, and run `pod install` from the Example directory first.
@@ -75,7 +78,9 @@ self.infiniteCollectionView.preferredCenteredIndexPath = [0, 0] // center the ce
self.infiniteCollectionView.preferredCenteredIndexPath = nil // center the closest cell from center
```
### Centered IndexPath
### Delegate
<img src="https://github.com/Arnoymous/InfiniteLayout/raw/master/delegate.gif" width="250" height="540">
InfiniteCollectionView provide an **infiniteDelegate** protocol used to get the centered IndexPath, usefull if you want to use an InfiniteCollectionView like a Picker.
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 572 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 688 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB