Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 03e9dbd3a4 | |||
| 1fbb837941 | |||
| 5746d5a7c4 | |||
| aacca75953 | |||
| 424edd4d73 | |||
| addf423ee2 | |||
| c11d525818 |
@@ -291,10 +291,12 @@
|
||||
);
|
||||
inputPaths = (
|
||||
"${SRCROOT}/Pods/Target Support Files/Pods-InfiniteLayout_Example/Pods-InfiniteLayout_Example-frameworks.sh",
|
||||
"${BUILT_PRODUCTS_DIR}/CocoaProxy/CocoaProxy.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/InfiniteLayout/InfiniteLayout.framework",
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CocoaProxy.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/InfiniteLayout.framework",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
PODS:
|
||||
- InfiniteLayout (0.1.0)
|
||||
- CocoaProxy (0.1.1)
|
||||
- InfiniteLayout (0.1.3):
|
||||
- CocoaProxy (~> 0.1)
|
||||
|
||||
DEPENDENCIES:
|
||||
- InfiniteLayout (from `../`)
|
||||
@@ -9,7 +11,8 @@ EXTERNAL SOURCES:
|
||||
:path: ../
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
InfiniteLayout: 82a21b8255623e2d72174f3082bef9e576140621
|
||||
CocoaProxy: 35ab81e24325b33834cffe45a3d1fd48ca67ef3a
|
||||
InfiniteLayout: 0ab39bf2a4d9ce5c473ebccfc0d3b7278de18ac9
|
||||
|
||||
PODFILE CHECKSUM: 3a658536624f41ec07c5a7a2c55407b9b8f48528
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
|
||||
Pod::Spec.new do |s|
|
||||
s.name = 'InfiniteLayout'
|
||||
s.version = '0.1.0'
|
||||
s.summary = 'Vertical and Horizontal infinite scrolling for UICollectionView'
|
||||
s.version = '0.1.4'
|
||||
s.summary = 'Horizontal and Vertical infinite scrolling feature for UICollectionView'
|
||||
|
||||
# This description is used to generate tags and improve search results.
|
||||
# * Think: What does it do? Why did you write it? What is the focus?
|
||||
@@ -18,7 +18,7 @@ Pod::Spec.new do |s|
|
||||
# * Finally, don't worry about the indent, CocoaPods strips it!
|
||||
|
||||
s.description = <<-DESC
|
||||
Vertical and Horizontal infinite scrolling for UICollectionView with Paging and NSProxy delegate
|
||||
Horizontal and Vertical infinite scrolling feature for UICollectionView with Paging and NSProxy delegate
|
||||
DESC
|
||||
|
||||
s.homepage = 'https://github.com/Arnoymous/InfiniteLayout'
|
||||
@@ -40,5 +40,5 @@ Vertical and Horizontal infinite scrolling for UICollectionView with Paging and
|
||||
|
||||
# s.public_header_files = 'Pod/Classes/**/*.h'
|
||||
# s.frameworks = 'UIKit', 'MapKit'
|
||||
# s.dependency 'AFNetworking', '~> 2.3'
|
||||
s.dependency 'CocoaProxy', '~> 0.1'
|
||||
end
|
||||
|
||||
@@ -9,10 +9,8 @@ import UIKit
|
||||
|
||||
open class InfiniteCollectionView: UICollectionView {
|
||||
|
||||
lazy var delegateProxy = InfiniteCollectionViewDelegateProxy(self, exceptions: ["scrollViewDidScroll:",
|
||||
"scrollViewWillEndDragging:withVelocity:targetContentOffset:"])
|
||||
lazy var dataSourceProxy = InfiniteCollectionViewDataSourceProxy(self, exceptions: ["numberOfSectionsInCollectionView:",
|
||||
"collectionView:numberOfItemsInSection:"])
|
||||
lazy var delegateProxy = InfiniteCollectionViewDelegateProxy(collectionView: self)
|
||||
lazy var dataSourceProxy = InfiniteCollectionViewDataSourceProxy(collectionView: self)
|
||||
|
||||
@IBInspectable var isItemPagingEnabled: Bool = false
|
||||
@IBInspectable var velocityMultiplier: CGFloat = 500 {
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
//
|
||||
// InfiniteCollectionViewProxy.h
|
||||
// InfiniteLayout
|
||||
//
|
||||
// Created by Arnaud Dorgans on 21/12/2017.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface _InfiniteCollectionViewProxy<T: id<NSObject>> : NSProxy <UICollectionViewDelegate, UICollectionViewDataSource>
|
||||
|
||||
-(nonnull instancetype)init:(nullable T)collectionView exceptions:(nonnull NSArray<NSString*>*)exceptions;
|
||||
|
||||
@property (nonatomic, weak, nullable) T collectionView;
|
||||
@property (nonatomic, weak, nullable) T delegate;
|
||||
@property (nonatomic, nonnull, retain) NSArray* exceptions;
|
||||
|
||||
|
||||
@end
|
||||
@@ -1,52 +0,0 @@
|
||||
//
|
||||
// InfiniteCollectionViewProxy.m
|
||||
// InfiniteLayout
|
||||
//
|
||||
// Created by Arnaud Dorgans on 21/12/2017.
|
||||
//
|
||||
|
||||
#import "InfiniteCollectionViewProxy.h"
|
||||
|
||||
@implementation _InfiniteCollectionViewProxy
|
||||
|
||||
-(instancetype)init:(nullable id)collectionView exceptions:(nonnull NSArray<NSString*>*)exceptions {
|
||||
self.collectionView = collectionView;
|
||||
self.exceptions = exceptions;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)respondsToSelector:(SEL)aSelector
|
||||
{
|
||||
return ([self.collectionView respondsToSelector:aSelector] || [self.delegate respondsToSelector:aSelector]);
|
||||
}
|
||||
|
||||
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
|
||||
NSObject *delegateForResonse = [self.delegate respondsToSelector:aSelector] ? self.delegate : self.collectionView;
|
||||
NSMethodSignature *signature = [delegateForResonse respondsToSelector:aSelector] ? [delegateForResonse methodSignatureForSelector:aSelector] : nil;
|
||||
return signature;
|
||||
}
|
||||
|
||||
- (void)forwardInvocation:(NSInvocation *)invocation
|
||||
{
|
||||
NSString *selectorName = NSStringFromSelector(invocation.selector);
|
||||
|
||||
NSArray<id<NSObject>> *delegates = @[self.delegate, self.collectionView];
|
||||
if ([self.exceptions containsObject:selectorName]) {
|
||||
delegates = [[delegates reverseObjectEnumerator] allObjects];
|
||||
}
|
||||
for (int i = 0; i < delegates.count; i++) {
|
||||
if ([delegates[i] respondsToSelector:invocation.selector]) {
|
||||
[self invokeInvocation:invocation onDelegate:delegates[i]];
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)invokeInvocation:(NSInvocation *)invocation onDelegate:(id<NSObject>)delegate
|
||||
{
|
||||
if ([delegate respondsToSelector:invocation.selector]) {
|
||||
[invocation invokeWithTarget:delegate];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,85 @@
|
||||
//
|
||||
// Proxy.swift
|
||||
// InfiniteLayout
|
||||
//
|
||||
// Created by Arnaud Dorgans on 20/12/2017.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import CocoaProxy
|
||||
|
||||
class InfiniteCollectionViewProxy<T: NSObjectProtocol>: CocoaProxy {
|
||||
|
||||
var collectionView: InfiniteCollectionView! {
|
||||
get { return self.proxies.first as? InfiniteCollectionView }
|
||||
set {
|
||||
if !self.proxies.isEmpty {
|
||||
self.proxies.removeFirst()
|
||||
}
|
||||
self.proxies.insert(newValue, at: 0)
|
||||
}
|
||||
}
|
||||
|
||||
var delegate: T? {
|
||||
get {
|
||||
guard self.proxies.count > 1 else {
|
||||
return nil
|
||||
}
|
||||
return self.proxies.last as? T
|
||||
} set {
|
||||
while self.proxies.count > 1 {
|
||||
self.proxies.removeLast()
|
||||
}
|
||||
guard let delegate = newValue else {
|
||||
return
|
||||
}
|
||||
self.proxies.append(delegate)
|
||||
}
|
||||
}
|
||||
|
||||
override func proxies(for aSelector: Selector) -> [NSObjectProtocol] {
|
||||
return super.proxies(for: aSelector).reversed()
|
||||
}
|
||||
|
||||
init(collectionView: InfiniteCollectionView) {
|
||||
super.init(proxies: [])
|
||||
self.collectionView = collectionView
|
||||
}
|
||||
}
|
||||
|
||||
class InfiniteCollectionViewDelegateProxy: InfiniteCollectionViewProxy<UICollectionViewDelegate>, UICollectionViewDelegate {
|
||||
|
||||
override func proxies(for aSelector: Selector) -> [NSObjectProtocol] {
|
||||
return super.proxies(for: aSelector)
|
||||
.first { proxy in
|
||||
guard !(aSelector == #selector(UIScrollViewDelegate.scrollViewDidScroll(_:)) ||
|
||||
aSelector == #selector(UIScrollViewDelegate.scrollViewWillEndDragging(_:withVelocity:targetContentOffset:))) else {
|
||||
return proxy is InfiniteCollectionView
|
||||
}
|
||||
return true
|
||||
}.flatMap { [$0] } ?? []
|
||||
}
|
||||
}
|
||||
|
||||
class InfiniteCollectionViewDataSourceProxy: InfiniteCollectionViewProxy<UICollectionViewDataSource>, UICollectionViewDataSource {
|
||||
|
||||
override func proxies(for aSelector: Selector) -> [NSObjectProtocol] {
|
||||
return super.proxies(for: aSelector)
|
||||
.first { proxy in
|
||||
guard !(aSelector == #selector(UICollectionViewDataSource.numberOfSections(in:)) ||
|
||||
aSelector == #selector(UICollectionViewDataSource.collectionView(_:numberOfItemsInSection:))) else {
|
||||
return proxy is InfiniteCollectionView
|
||||
}
|
||||
return true
|
||||
}.flatMap { [$0] } ?? []
|
||||
}
|
||||
|
||||
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
||||
return self.collectionView.collectionView(collectionView, numberOfItemsInSection: section)
|
||||
}
|
||||
|
||||
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
||||
return self.delegate?.collectionView(collectionView, cellForItemAt: indexPath) ??
|
||||
self.collectionView.collectionView(collectionView, cellForItemAt: indexPath)
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
//
|
||||
// Proxy.swift
|
||||
// InfiniteLayout
|
||||
//
|
||||
// Created by Arnaud Dorgans on 20/12/2017.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class InfiniteCollectionViewDelegateProxy: _InfiniteCollectionViewProxy<UICollectionViewDelegate> {
|
||||
|
||||
}
|
||||
|
||||
class InfiniteCollectionViewDataSourceProxy: _InfiniteCollectionViewProxy<UICollectionViewDataSource> {
|
||||
|
||||
}
|
||||
@@ -20,6 +20,45 @@ it, simply add the following line to your Podfile:
|
||||
pod 'InfiniteLayout'
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```swift
|
||||
@IBOutlet weak var collectionView: InfiniteCollectionView!
|
||||
```
|
||||
|
||||
InfiniteCollectionView doesn't need any other delegate or dataSource,
|
||||
just use UICollectionViewDataSource and UICollectionViewDelegate in the same way as you'll use it in any other UICollectionView.
|
||||
|
||||
InfiniteLayout provides 3 classes for infinite scrolling:
|
||||
|
||||
**InfiniteLayout**: an UICollectionViewFlowLayout
|
||||
|
||||
**InfiniteCollectionView**: an UICollectionView with InfiniteLayout
|
||||
|
||||
**InfiniteCollectionViewController**: an UICollectionViewController with InfiniteCollectionView
|
||||
|
||||
### IndexPath
|
||||
|
||||
InfiniteCollectionView may create fake indexPath,
|
||||
|
||||
To get the real indexPath call
|
||||
|
||||
```swift
|
||||
func indexPath(from infiniteIndexPath: IndexPath) -> IndexPath
|
||||
```
|
||||
|
||||
To get the real section call
|
||||
|
||||
```swift
|
||||
func section(from infiniteSection: Int) -> Int
|
||||
```
|
||||
|
||||
### Paging
|
||||
|
||||
InfiniteCollectionView provide a paging functionality, you can enable it by setting the **isItemPagingEnabled** flag to **true**,
|
||||
|
||||
When the **isItemPagingEnabled** flag is enabled you can adjust the deceleration rate by setting the **velocityMultiplier**, the more the value is high, the more the deceleration is long
|
||||
|
||||
## Author
|
||||
|
||||
Arnoymous, ineox@me.com
|
||||
|
||||
Reference in New Issue
Block a user