Compare commits

..

3 Commits

Author SHA1 Message Date
Arnaud Dorgans 03e9dbd3a4 add CocoaProxy 2017-12-27 23:26:31 +01:00
Arnaud Dorgans 1fbb837941 update 2017-12-25 18:36:20 +01:00
Arnaud Dorgans 5746d5a7c4 Update README.md 2017-12-25 18:30:35 +01:00
9 changed files with 122 additions and 100 deletions
@@ -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;
+5 -2
View File
@@ -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
+4 -4
View File
@@ -8,8 +8,8 @@
Pod::Spec.new do |s|
s.name = 'InfiniteLayout'
s.version = '0.1.1'
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)
}
}
-16
View File
@@ -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> {
}
+24 -3
View File
@@ -26,10 +26,10 @@ pod 'InfiniteLayout'
@IBOutlet weak var collectionView: InfiniteCollectionView!
```
InfiniteCollectionView don't need any other delegate or dataSource,
just use UICollectionViewDataSource and UICollectionViewDelegate as you'll use it in any other UICollectionView.
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 provide 3 class for infinite scrolling:
InfiniteLayout provides 3 classes for infinite scrolling:
**InfiniteLayout**: an UICollectionViewFlowLayout
@@ -37,6 +37,27 @@ InfiniteLayout provide 3 class for infinite scrolling:
**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