Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 227269190f | |||
| 38f6b056f1 | |||
| 90a0ce56da | |||
| 0e9d75b59d | |||
| da9c8b1372 | |||
| 83960eb567 | |||
| cae11d5404 | |||
| ab7324dc5b | |||
| 8cd7e843af | |||
| 519d724e17 | |||
| d80114e454 | |||
| 1d4c698ab0 |
@@ -1 +0,0 @@
|
||||
5.0
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
@@ -331,6 +331,7 @@
|
||||
"${BUILT_PRODUCTS_DIR}/InfiniteLayout/InfiniteLayout.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/RxCocoa/RxCocoa.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/RxDataSources/RxDataSources.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/RxRelay/RxRelay.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/RxSwift/RxSwift.framework",
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
@@ -340,6 +341,7 @@
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/InfiniteLayout.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RxCocoa.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RxDataSources.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RxRelay.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RxSwift.framework",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
||||
+25
-20
@@ -1,24 +1,27 @@
|
||||
PODS:
|
||||
- CocoaProxy (0.1.1)
|
||||
- Differentiator (3.1.0)
|
||||
- InfiniteLayout (0.3):
|
||||
- Differentiator (4.0.1)
|
||||
- InfiniteLayout (0.4.1):
|
||||
- CocoaProxy (~> 0)
|
||||
- InfiniteLayout/Core (= 0.3)
|
||||
- InfiniteLayout/Core (0.3):
|
||||
- InfiniteLayout/Core (= 0.4.1)
|
||||
- InfiniteLayout/Core (0.4.1):
|
||||
- CocoaProxy (~> 0)
|
||||
- InfiniteLayout/Rx (0.3):
|
||||
- InfiniteLayout/Rx (0.4.1):
|
||||
- CocoaProxy (~> 0)
|
||||
- InfiniteLayout/Core (~> 0)
|
||||
- RxCocoa (~> 4)
|
||||
- RxDataSources (~> 3)
|
||||
- RxSwift (~> 4)
|
||||
- RxCocoa (4.5.0):
|
||||
- RxSwift (>= 4.4.2, ~> 4.4)
|
||||
- RxDataSources (3.1.0):
|
||||
- Differentiator (~> 3.0)
|
||||
- RxCocoa (~> 4.0)
|
||||
- RxSwift (~> 4.0)
|
||||
- RxSwift (4.5.0)
|
||||
- RxCocoa (~> 5)
|
||||
- RxDataSources (~> 4)
|
||||
- RxSwift (~> 5)
|
||||
- RxCocoa (5.0.0):
|
||||
- RxRelay (~> 5)
|
||||
- RxSwift (~> 5)
|
||||
- RxDataSources (4.0.1):
|
||||
- Differentiator (~> 4.0)
|
||||
- RxCocoa (~> 5.0)
|
||||
- RxSwift (~> 5.0)
|
||||
- RxRelay (5.0.0):
|
||||
- RxSwift (~> 5)
|
||||
- RxSwift (5.0.0)
|
||||
|
||||
DEPENDENCIES:
|
||||
- InfiniteLayout (from `../`)
|
||||
@@ -30,6 +33,7 @@ SPEC REPOS:
|
||||
- Differentiator
|
||||
- RxCocoa
|
||||
- RxDataSources
|
||||
- RxRelay
|
||||
- RxSwift
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
@@ -38,11 +42,12 @@ EXTERNAL SOURCES:
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
CocoaProxy: 35ab81e24325b33834cffe45a3d1fd48ca67ef3a
|
||||
Differentiator: be49ca3408f0ecfc761e4c7763d20c62be01b9ad
|
||||
InfiniteLayout: 24d5e5ea1528bb86ee00a4e3c02f93fdb38e3f68
|
||||
RxCocoa: cbf70265dc65a981d4ac982e513c10cf23df24a0
|
||||
RxDataSources: a843bad90c29817f5923ec8163f4af2de084ceb3
|
||||
RxSwift: f172070dfd1a93d70a9ab97a5a01166206e1c575
|
||||
Differentiator: 886080237d9f87f322641dedbc5be257061b0602
|
||||
InfiniteLayout: 458eadbcb94afc3d777141990fbfe7a804a35609
|
||||
RxCocoa: fcf32050ac00d801f34a7f71d5e8e7f23026dcd8
|
||||
RxDataSources: efee07fa4de48477eca0a4611e6d11e2da9c1114
|
||||
RxRelay: 4f7409406a51a55cd88483f21ed898c234d60f18
|
||||
RxSwift: 8b0671caa829a763bbce7271095859121cbd895f
|
||||
|
||||
PODFILE CHECKSUM: 0dc7a9b37f9b7c5d5266beaab9e94861b80aa80f
|
||||
|
||||
|
||||
+14
-10
@@ -8,7 +8,7 @@
|
||||
|
||||
Pod::Spec.new do |s|
|
||||
s.name = 'InfiniteLayout'
|
||||
s.version = '0.4'
|
||||
s.version = '0.4.2'
|
||||
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.
|
||||
@@ -39,19 +39,23 @@ Horizontal and Vertical infinite scrolling feature for UICollectionView with Pag
|
||||
|
||||
# s.public_header_files = 'Pod/Classes/**/*.h'
|
||||
# s.frameworks = 'UIKit', 'MapKit'
|
||||
s.dependency 'CocoaProxy', '~> 0'
|
||||
s.swift_versions = ['5.0', '5.1']
|
||||
|
||||
|
||||
s.default_subspec = 'Core'
|
||||
|
||||
s.subspec 'Core' do |core|
|
||||
core.source_files = 'InfiniteLayout/Classes/**/*'
|
||||
core.source_files = 'Sources/InfiniteLayout/**/*'
|
||||
core.dependency 'InfiniteLayout/CocoaProxy'
|
||||
core.exclude_files = '**/*/SPMBridge.swift'
|
||||
end
|
||||
s.subspec 'CocoaProxy' do |core|
|
||||
core.source_files = 'Sources/CocoaProxy/**/*'
|
||||
end
|
||||
|
||||
s.subspec 'Rx' do |rx|
|
||||
rx.dependency 'InfiniteLayout/Core', '~> 0'
|
||||
rx.dependency 'RxSwift', '~> 4.5'
|
||||
rx.dependency 'RxCocoa', '~> 4.5'
|
||||
rx.dependency 'RxDataSources', '~> 3.1'
|
||||
rx.source_files = 'InfiniteLayout/Rx/**/*'
|
||||
rx.dependency 'InfiniteLayout/Core'
|
||||
rx.dependency 'RxSwift', '~> 5'
|
||||
rx.dependency 'RxCocoa', '~> 5'
|
||||
rx.dependency 'RxDataSources', '~> 4'
|
||||
rx.source_files = 'Sources/Rx/**/*'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
// swift-tools-version:5.0
|
||||
// The swift-tools-version declares the minimum version of Swift required to build this package.
|
||||
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "InfiniteLayout",
|
||||
platforms: [.iOS(.v8), .tvOS(.v9)],
|
||||
products: [
|
||||
// Products define the executables and libraries produced by a package, and make them visible to other packages.
|
||||
.library(
|
||||
name: "InfiniteLayout",
|
||||
targets: ["InfiniteLayout"]),
|
||||
],
|
||||
dependencies: [
|
||||
// Dependencies declare other packages that this package depends on.
|
||||
// .package(url: /* package url */, from: "1.0.0"),
|
||||
],
|
||||
targets: [
|
||||
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
|
||||
// Targets can depend on other targets in this package, and on products in packages which this package depends on.
|
||||
.target(
|
||||
name: "CocoaProxy",
|
||||
dependencies: [],
|
||||
publicHeadersPath: "./"),
|
||||
.target(
|
||||
name: "InfiniteLayout",
|
||||
dependencies: ["CocoaProxy"])
|
||||
]
|
||||
)
|
||||
@@ -1,9 +1,10 @@
|
||||
# InfiniteLayout
|
||||
|
||||
[](https://travis-ci.org/arnauddorgans/InfiniteLayout)
|
||||
[](http://cocoapods.org/pods/InfiniteLayout)
|
||||
[](http://cocoapods.org/pods/InfiniteLayout)
|
||||
[](http://cocoapods.org/pods/InfiniteLayout)
|
||||
[](http://cocoapods.org/pods/InfiniteLayout)
|
||||
[](https://github.com/apple/swift-package-manager)
|
||||
|
||||
<img src="https://github.com/arnauddorgans/InfiniteLayout/raw/master/horizontal.gif" width="250" height="540"><img src="https://github.com/arnauddorgans/InfiniteLayout/raw/master/vertical.gif" width="250" height="540"><img src="https://github.com/arnauddorgans/InfiniteLayout/raw/master/custom.gif" width="250" height="540">
|
||||
|
||||
@@ -12,10 +13,10 @@
|
||||
|
||||
To run the example project, clone the repo, and run `pod install` from the Example directory first.
|
||||
|
||||
## Requirements
|
||||
|
||||
## Installation
|
||||
|
||||
### [CocoaPods](https://guides.cocoapods.org/using/using-cocoapods.html)
|
||||
|
||||
InfiniteLayout is available through [CocoaPods](http://cocoapods.org). To install
|
||||
it, simply add the following line to your Podfile:
|
||||
|
||||
@@ -23,6 +24,27 @@ it, simply add the following line to your Podfile:
|
||||
pod 'InfiniteLayout'
|
||||
```
|
||||
|
||||
|
||||
### [Swift Package Manager](https://github.com/apple/swift-package-manager)
|
||||
|
||||
Create a `Package.swift` file.
|
||||
|
||||
```swift
|
||||
// swift-tools-version:5.0
|
||||
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "InfiniteLayoutTestProject",
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/arnauddorgans/InfiniteLayout.git", from: "0.4.2")
|
||||
],
|
||||
targets: [
|
||||
.target(name: "InfiniteLayoutTestProject", dependencies: ["InfiniteLayout"])
|
||||
]
|
||||
)
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```swift
|
||||
@@ -85,7 +107,7 @@ self.infiniteCollectionView.preferredCenteredIndexPath = nil // center the close
|
||||
InfiniteCollectionView provide an **infiniteDelegate** protocol used to get the centered IndexPath, usefull if you want to use an InfiniteCollectionView like a Picker.
|
||||
|
||||
```swift
|
||||
func infiniteCollectionView(_ infiniteCollectionView: InfiniteCollectionView, didChangeCenteredIndexPath centeredIndexPath: IndexPath?)
|
||||
func infiniteCollectionView(_ infiniteCollectionView: InfiniteCollectionView, didChangeCenteredIndexPath from: IndexPath?, to: IndexPath?)
|
||||
```
|
||||
|
||||
### Rx
|
||||
|
||||
Executable
+20
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// CocoaProxy.h
|
||||
// CocoaProxy
|
||||
//
|
||||
// Created by Arnaud Dorgans on 27/12/2017.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface CocoaProxy : NSProxy
|
||||
|
||||
- (instancetype _Nonnull)init;
|
||||
- (instancetype _Nonnull)initWithProxies:(nonnull NSArray<id<NSObject>>*)proxies;
|
||||
|
||||
- (NSArray<id<NSObject>> *_Nonnull)proxiesForSelector:(SEL _Nonnull )aSelector;
|
||||
|
||||
@property (nonatomic, strong) NSArray<id<NSObject>>* _Nonnull proxies;
|
||||
@property (nonatomic, copy) BOOL (^ _Nullable proxyFilter)(id<NSObject> _Nonnull proxy, SEL _Nonnull selector);
|
||||
|
||||
@end
|
||||
Executable
+80
@@ -0,0 +1,80 @@
|
||||
//
|
||||
// CocoaProxy.m
|
||||
// CocoaProxy
|
||||
//
|
||||
// Created by Arnaud Dorgans on 27/12/2017.
|
||||
//
|
||||
|
||||
#import "CocoaProxy.h"
|
||||
|
||||
@interface CocoaProxy () { }
|
||||
|
||||
@property (nonatomic, strong) NSPointerArray *pointerArray;
|
||||
|
||||
@end
|
||||
|
||||
@implementation CocoaProxy
|
||||
|
||||
- (instancetype _Nonnull)initWithProxies:(nonnull NSArray<NSObject*>*)proxies {
|
||||
[self setProxies: proxies];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype _Nonnull)init {
|
||||
return [self initWithProxies: @[]];
|
||||
}
|
||||
|
||||
- (BOOL)respondsToSelector:(SEL)aSelector
|
||||
{
|
||||
return ([self methodSignatureForSelector: aSelector] != nil);
|
||||
}
|
||||
|
||||
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
|
||||
{
|
||||
for (NSObject* proxy in [self proxiesForSelector: aSelector]) {
|
||||
if ([proxy respondsToSelector: aSelector]) {
|
||||
return [proxy methodSignatureForSelector: aSelector];
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSArray<id<NSObject>> *_Nonnull)proxiesForSelector:(SEL _Nonnull )aSelector
|
||||
{
|
||||
if (self.proxyFilter) {
|
||||
NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id _Nullable evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) {
|
||||
return self.proxyFilter(evaluatedObject, aSelector);
|
||||
}];
|
||||
return [self.proxies filteredArrayUsingPredicate: predicate];
|
||||
}
|
||||
return self.proxies;
|
||||
}
|
||||
|
||||
- (void)forwardInvocation:(NSInvocation *)invocation
|
||||
{
|
||||
for (NSObject* proxy in [self proxiesForSelector: invocation.selector]) {
|
||||
[self invokeInvocation: invocation onProxy: proxy];
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)invokeInvocation:(NSInvocation *)invocation onProxy:(id<NSObject>)proxy
|
||||
{
|
||||
if ([proxy respondsToSelector: invocation.selector]) {
|
||||
[invocation invokeWithTarget: proxy];
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)setProxies:(NSArray<id<NSObject>> *)proxies {
|
||||
self.pointerArray = [NSPointerArray weakObjectsPointerArray];
|
||||
for (NSObject* proxy in proxies) {
|
||||
[self.pointerArray addPointer: (void *)proxy];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSArray<id<NSObject>> *)proxies {
|
||||
return self.pointerArray.allObjects;
|
||||
}
|
||||
|
||||
@end
|
||||
+4
-3
@@ -8,8 +8,8 @@
|
||||
import UIKit
|
||||
|
||||
@objc public protocol InfiniteCollectionViewDelegate {
|
||||
|
||||
@objc optional func infiniteCollectionView(_ infiniteCollectionView: InfiniteCollectionView, didChangeCenteredIndexPath centeredIndexPath: IndexPath?)
|
||||
|
||||
@objc optional func infiniteCollectionView(_ infiniteCollectionView: InfiniteCollectionView, didChangeCenteredIndexPath from: IndexPath?, to: IndexPath?)
|
||||
}
|
||||
|
||||
open class InfiniteCollectionView: UICollectionView {
|
||||
@@ -170,8 +170,9 @@ extension InfiniteCollectionView: UICollectionViewDelegate {
|
||||
|
||||
let preferredVisibleIndexPath = infiniteLayout.preferredVisibleLayoutAttributes()?.indexPath
|
||||
if self.centeredIndexPath != preferredVisibleIndexPath {
|
||||
let previousCenteredIndexPath = self.centeredIndexPath
|
||||
self.centeredIndexPath = preferredVisibleIndexPath
|
||||
self.infiniteDelegate?.infiniteCollectionView?(self, didChangeCenteredIndexPath: preferredVisibleIndexPath)
|
||||
self.infiniteDelegate?.infiniteCollectionView?(self, didChangeCenteredIndexPath: previousCenteredIndexPath, to: self.centeredIndexPath)
|
||||
}
|
||||
}
|
||||
|
||||
-1
@@ -6,7 +6,6 @@
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import CocoaProxy
|
||||
|
||||
class InfiniteCollectionViewProxy<T: NSObjectProtocol>: CocoaProxy {
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
//
|
||||
// InfiniteCollectionView.swift
|
||||
// InfiniteLayout
|
||||
//
|
||||
// Created by Arnaud Dorgans on 05/09/2019.
|
||||
//
|
||||
|
||||
@_exported import CocoaProxy
|
||||
+3
-3
@@ -38,7 +38,7 @@ extension Reactive where Base: InfiniteCollectionView {
|
||||
}
|
||||
|
||||
public var itemCentered: ControlEvent<IndexPath?> {
|
||||
let source = infiniteDelegate.sentMessage(#selector(InfiniteCollectionViewDelegate.infiniteCollectionView(_:didChangeCenteredIndexPath:)))
|
||||
let source = infiniteDelegate.sentMessage(#selector(InfiniteCollectionViewDelegate.infiniteCollectionView(_:didChangeCenteredIndexPath:to:)))
|
||||
.map { $0.last as? IndexPath }
|
||||
return ControlEvent(events: source)
|
||||
}
|
||||
@@ -58,7 +58,7 @@ extension Reactive where Base: RxInfiniteCollectionView {
|
||||
(infinite: Bool)
|
||||
-> (_ source: O)
|
||||
-> (_ cellFactory: @escaping (UICollectionView, Int, S.Iterator.Element) -> UICollectionViewCell)
|
||||
-> Disposable where O.E == S {
|
||||
-> Disposable where O.Element == S {
|
||||
return { source in
|
||||
guard infinite else {
|
||||
return self.items(source)
|
||||
@@ -76,7 +76,7 @@ extension Reactive where Base: RxInfiniteCollectionView {
|
||||
(cellIdentifier: String, cellType: Cell.Type = Cell.self, infinite: Bool)
|
||||
-> (_ source: O)
|
||||
-> (_ configureCell: @escaping (Int, S.Iterator.Element, Cell) -> Void)
|
||||
-> Disposable where O.E == S {
|
||||
-> Disposable where O.Element == S {
|
||||
guard infinite else {
|
||||
return self.items(cellIdentifier: cellIdentifier, cellType: cellType)
|
||||
}
|
||||
+2
-2
@@ -17,7 +17,7 @@ open class RxInfiniteCollectionViewSectionedReloadDataSource<S: SectionModelType
|
||||
return self.sectionModels[section]
|
||||
}
|
||||
|
||||
open override subscript(indexPath: IndexPath) -> I {
|
||||
open override subscript(indexPath: IndexPath) -> Item {
|
||||
get {
|
||||
let indexPath = InfiniteDataSources.indexPath(from: indexPath,
|
||||
numberOfSections: sectionModels.count,
|
||||
@@ -63,7 +63,7 @@ open class RxInfiniteCollectionViewSectionedAnimatedDataSource<S: AnimatableSect
|
||||
return self.sectionModels[section]
|
||||
}
|
||||
|
||||
open override subscript(indexPath: IndexPath) -> I {
|
||||
open override subscript(indexPath: IndexPath) -> Item {
|
||||
get {
|
||||
let indexPath = InfiniteDataSources.indexPath(from: indexPath,
|
||||
numberOfSections: sectionModels.count,
|
||||
Reference in New Issue
Block a user