Compare commits

...

9 Commits

Author SHA1 Message Date
Arnaud Dorgans 227269190f Merge pull request #13 from arnauddorgans/release/0.4.2
0.4.2
2019-09-05 18:14:46 +02:00
Arnaud Dorgans 38f6b056f1 Update README.md 2019-09-05 18:13:40 +02:00
Arnaud Dorgans 90a0ce56da release(0.4.2) @dlbuckley pr, Swift Package Manager 2019-09-05 18:02:11 +02:00
Arnaud Dorgans 0e9d75b59d Update README.md 2019-09-05 16:42:16 +02:00
Arnaud Dorgans da9c8b1372 Merge pull request #12 from dlbuckley/feature/add_willChangeCenteredIndexPath
Added willChangeCenteredIndexPath method to InfiniteCollectionViewDelegate protocol
2019-09-05 16:40:21 +02:00
Dale Buckley 83960eb567 rx fix 2019-09-05 12:15:27 +01:00
Dale Buckley cae11d5404 fixed a typo 2019-09-05 11:57:12 +01:00
Dale Buckley ab7324dc5b refactored based on code review comments by @arnauddorgans 2019-09-05 11:53:15 +01:00
Dale Buckley 8cd7e843af Added willChangeCenteredIndexPath method to InfiniteCollectionViewDelegate protocol 2019-08-29 15:08:01 +01:00
18 changed files with 187 additions and 17 deletions
-1
View File
@@ -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>
+11 -7
View File
@@ -8,7 +8,7 @@
Pod::Spec.new do |s|
s.name = 'InfiniteLayout'
s.version = '0.4.1'
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 'InfiniteLayout/Core'
rx.dependency 'RxSwift', '~> 5'
rx.dependency 'RxCocoa', '~> 5'
rx.dependency 'RxDataSources', '~> 4'
rx.source_files = 'InfiniteLayout/Rx/**/*'
rx.source_files = 'Sources/Rx/**/*'
end
end
View File
View File
+30
View File
@@ -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"])
]
)
+26 -4
View File
@@ -1,9 +1,10 @@
# InfiniteLayout
[![CI Status](http://img.shields.io/travis/arnauddorgans/InfiniteLayout.svg?style=flat)](https://travis-ci.org/arnauddorgans/InfiniteLayout)
[![Version](https://img.shields.io/cocoapods/v/InfiniteLayout.svg?style=flat)](http://cocoapods.org/pods/InfiniteLayout)
[![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)
[![Version](https://img.shields.io/cocoapods/v/InfiniteLayout.svg?style=flat)](http://cocoapods.org/pods/InfiniteLayout)
[![Swift Package Manager compatible](https://img.shields.io/badge/Swift%20Package%20Manager-compatible-brightgreen.svg)](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
+20
View File
@@ -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
+80
View File
@@ -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
@@ -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)
}
}
@@ -6,7 +6,6 @@
//
import UIKit
import CocoaProxy
class InfiniteCollectionViewProxy<T: NSObjectProtocol>: CocoaProxy {
+8
View File
@@ -0,0 +1,8 @@
//
// InfiniteCollectionView.swift
// InfiniteLayout
//
// Created by Arnaud Dorgans on 05/09/2019.
//
@_exported import CocoaProxy
@@ -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)
}