Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 0 additions & 61 deletions Example/FlexDataSource.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,6 @@
607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDC1AFB9204008FA782 /* Images.xcassets */; };
607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; };
60F5B00A42193B3AF34EFF1F /* Pods_FlexDataSource_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 70B1472C8F94AAAB3D29C47C /* Pods_FlexDataSource_Tests.framework */; };
6431743A265C542400BB682B /* FlexSimpleDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6431742F265C542400BB682B /* FlexSimpleDataSource.swift */; };
6431743B265C542400BB682B /* Array+Flex.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64317430265C542400BB682B /* Array+Flex.swift */; };
6431743C265C542400BB682B /* FlexDataSourceSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64317431265C542400BB682B /* FlexDataSourceSection.swift */; };
6431743D265C542400BB682B /* Swipeable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64317432265C542400BB682B /* Swipeable.swift */; };
6431743E265C542400BB682B /* FlexTitledDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64317433265C542400BB682B /* FlexTitledDataSource.swift */; };
6431743F265C542400BB682B /* Tappable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64317434265C542400BB682B /* Tappable.swift */; };
64317440265C542400BB682B /* FlexCollectionDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64317435265C542400BB682B /* FlexCollectionDataSource.swift */; };
64317441265C542400BB682B /* FlexDataSourceItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64317436265C542400BB682B /* FlexDataSourceItem.swift */; };
64317442265C542400BB682B /* FlexDataSourceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64317437265C542400BB682B /* FlexDataSourceProtocol.swift */; };
64317443265C542400BB682B /* FlexCollectionSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64317438265C542400BB682B /* FlexCollectionSection.swift */; };
64317444265C542400BB682B /* FlexCollectionItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64317439265C542400BB682B /* FlexCollectionItem.swift */; };
89D097AA605F356244FA4433 /* Pods_FlexDataSource_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B58498B2EB53A67483D9A3E4 /* Pods_FlexDataSource_Example.framework */; };
/* End PBXBuildFile section */

Expand Down Expand Up @@ -69,17 +58,6 @@
607FACEA1AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
6431742A265C53D800BB682B /* flex_data_sourceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = flex_data_sourceTests.swift; sourceTree = "<group>"; };
6431742E265C53D800BB682B /* Package.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Package.swift; path = ../Package.swift; sourceTree = "<group>"; };
6431742F265C542400BB682B /* FlexSimpleDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FlexSimpleDataSource.swift; sourceTree = "<group>"; };
64317430265C542400BB682B /* Array+Flex.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Array+Flex.swift"; sourceTree = "<group>"; };
64317431265C542400BB682B /* FlexDataSourceSection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FlexDataSourceSection.swift; sourceTree = "<group>"; };
64317432265C542400BB682B /* Swipeable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Swipeable.swift; sourceTree = "<group>"; };
64317433265C542400BB682B /* FlexTitledDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FlexTitledDataSource.swift; sourceTree = "<group>"; };
64317434265C542400BB682B /* Tappable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Tappable.swift; sourceTree = "<group>"; };
64317435265C542400BB682B /* FlexCollectionDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FlexCollectionDataSource.swift; sourceTree = "<group>"; };
64317436265C542400BB682B /* FlexDataSourceItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FlexDataSourceItem.swift; sourceTree = "<group>"; };
64317437265C542400BB682B /* FlexDataSourceProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FlexDataSourceProtocol.swift; sourceTree = "<group>"; };
64317438265C542400BB682B /* FlexCollectionSection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FlexCollectionSection.swift; sourceTree = "<group>"; };
64317439265C542400BB682B /* FlexCollectionItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FlexCollectionItem.swift; sourceTree = "<group>"; };
70B1472C8F94AAAB3D29C47C /* Pods_FlexDataSource_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_FlexDataSource_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
879D79256B72CCA876FDF46B /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = "<group>"; };
88E8F3051D2D88F16AFB7F97 /* FlexDataSource.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = FlexDataSource.podspec; path = ../FlexDataSource.podspec; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
Expand Down Expand Up @@ -123,7 +101,6 @@
children = (
23D949362718EFCF0008D371 /* .circleci */,
6431742E265C53D800BB682B /* Package.swift */,
6431742B265C53D800BB682B /* Sources */,
64317428265C53D800BB682B /* Tests */,
494C77C1242E6DD200B8C018 /* Example.playground */,
607FACF51AFB993E008FA782 /* Podspec Metadata */,
Expand Down Expand Up @@ -217,33 +194,6 @@
path = "flex-data-sourceTests";
sourceTree = "<group>";
};
6431742B265C53D800BB682B /* Sources */ = {
isa = PBXGroup;
children = (
6431742C265C53D800BB682B /* flex-data-source */,
);
name = Sources;
path = ../Sources;
sourceTree = "<group>";
};
6431742C265C53D800BB682B /* flex-data-source */ = {
isa = PBXGroup;
children = (
64317430265C542400BB682B /* Array+Flex.swift */,
64317435265C542400BB682B /* FlexCollectionDataSource.swift */,
64317439265C542400BB682B /* FlexCollectionItem.swift */,
64317438265C542400BB682B /* FlexCollectionSection.swift */,
64317437265C542400BB682B /* FlexDataSourceProtocol.swift */,
64317436265C542400BB682B /* FlexDataSourceItem.swift */,
64317431265C542400BB682B /* FlexDataSourceSection.swift */,
6431742F265C542400BB682B /* FlexSimpleDataSource.swift */,
64317433265C542400BB682B /* FlexTitledDataSource.swift */,
64317432265C542400BB682B /* Swipeable.swift */,
64317434265C542400BB682B /* Tappable.swift */,
);
path = "flex-data-source";
sourceTree = "<group>";
};
CBB51F0C6B4320961CD22F51 /* Pods */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -444,19 +394,8 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
6431743B265C542400BB682B /* Array+Flex.swift in Sources */,
6431743A265C542400BB682B /* FlexSimpleDataSource.swift in Sources */,
6431743F265C542400BB682B /* Tappable.swift in Sources */,
64317440265C542400BB682B /* FlexCollectionDataSource.swift in Sources */,
6431743C265C542400BB682B /* FlexDataSourceSection.swift in Sources */,
607FACD81AFB9204008FA782 /* ViewController.swift in Sources */,
64317443265C542400BB682B /* FlexCollectionSection.swift in Sources */,
64317441265C542400BB682B /* FlexDataSourceItem.swift in Sources */,
6431743E265C542400BB682B /* FlexTitledDataSource.swift in Sources */,
6431743D265C542400BB682B /* Swipeable.swift in Sources */,
64317442265C542400BB682B /* FlexDataSourceProtocol.swift in Sources */,
607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */,
64317444265C542400BB682B /* FlexCollectionItem.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
2 changes: 1 addition & 1 deletion Example/Tests/FlexCollectionItemTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class FlexCollectionItemTests: XCTestCase {
pressed = true
}
item.configureCell(cell)
item.onTap()
item.onTap?()
XCTAssertEqual(cell.backgroundColor, .red)
XCTAssertEqual(item.cellIdentifier(), cellID)
XCTAssertTrue(pressed == true)
Expand Down
7 changes: 3 additions & 4 deletions Example/Tests/FlexDataSourceItemTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import LithoOperators
@testable import FlexDataSource

class FlexDataSourceItemTests: XCTestCase {

func testFunctionalFlexDataSourceItem() {
let identifier = "TableViewCell"
let item = FunctionalFlexDataSourceItem<UITableViewCell>(identifier: identifier, set(\UITableViewCell.backgroundColor, .red))
Expand All @@ -38,7 +37,7 @@ class FlexDataSourceItemTests: XCTestCase {
pressed = true
}
item.configureCell(cell)
item.onTap()
item.onTap?()
XCTAssertEqual(cell.backgroundColor, .red)
XCTAssertEqual(item.cellIdentifier(), cellID)
XCTAssertTrue(pressed)
Expand All @@ -51,8 +50,8 @@ class FlexDataSourceItemTests: XCTestCase {
let cell = UITableViewCell()
let item = SwipableItem<UITableViewCell>(identifier: cellID, set(\UITableViewCell.backgroundColor, .blue), { wasTapped = true }, {wasSwiped = true})
item.configureCell(cell)
item.onTap()
item.onSwipe()
item.onTap?()
item.onSwipe?()
XCTAssertEqual(cell.backgroundColor, .blue)
XCTAssertEqual(item.cellIdentifier(), cellID)
XCTAssertTrue(wasSwiped == true)
Expand Down
10 changes: 5 additions & 5 deletions Example/Tests/FlexItemsTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ class FlexItemTests: XCTestCase {
}
let configurer: (Human, UITableViewCell) -> Void = setMainLabel
var wasTapped: Bool = false
let item = FlexTappableModelItem<Human, UITableViewCell>(model: Human(id: 123, name: "Calvin Collins"), configurer: configurer, tap: { _ in
let item = FlexModelItem<Human, UITableViewCell>(model: Human(id: 123, name: "Calvin Collins"), configurer: configurer, tap: { _ in
wasTapped = true
})
item.onTap()
item.onTap?()
XCTAssert(wasTapped)
}

Expand All @@ -47,13 +47,13 @@ class FlexItemTests: XCTestCase {
let configurer: (Human, UITableViewCell) -> Void = setMainLabel
var wasSwiped: Bool = false
var wasTapped: Bool = false
let item = FlexSwipeTapModelItem<Human, UITableViewCell>(model: Human(id: 123, name: "Calvin Collins"), configurer: configurer, tap: { _ in
let item = FlexModelItem<Human, UITableViewCell>(model: Human(id: 123, name: "Calvin Collins"), configurer: configurer, tap: { _ in
wasTapped = true
}, swipe: { _ in
wasSwiped = true
})
item.onSwipe()
item.onTap()
item.onSwipe?()
item.onTap?()
XCTAssert(wasTapped && wasSwiped)
}
}
12 changes: 11 additions & 1 deletion Sources/flex-data-source/FlexCollectionDataSource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,16 @@ open class FlexCollectionDataSource: FPUICollectionViewDatasource {
}
return UICollectionViewCell()
}

open func setSections(_ sections: [FlexCollectionSection]?) {
self.sections = sections
collectionView?.reloadData()
}

open func setItems(_ items: [FlexCollectionItem]?) {
let section = FlexCollectionSection(title: nil, items: items)
setSections([section])
}
}

// MARK: - Tapping
Expand All @@ -76,7 +86,7 @@ public extension FlexCollectionDataSource {
func tappableOnSelect(_ collectionView: UICollectionView, _ indexPath: IndexPath) -> Void {
collectionView.deselectItem(at: indexPath, animated: true)
if let tappable = sections?[indexPath.section].items?[indexPath.row] as? Tappable {
tappable.onTap()
tappable.onTap?()
}
}

Expand Down
2 changes: 1 addition & 1 deletion Sources/flex-data-source/FlexCollectionItem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ open class FunctionalFlexCollectionItem<T>: ConcreteFlexCollectionItem<T> where
}

open class TappableFlexCollectionItem<T>: FunctionalFlexCollectionItem<T>, Tappable where T: UICollectionViewCell {
public var onTap: () -> Void
public var onTap: (() -> Void)?

public init(identifier: String, _ configureCell: @escaping (UICollectionViewCell) -> Void, _ onTap: @escaping () -> Void) {
self.onTap = onTap
Expand Down
45 changes: 19 additions & 26 deletions Sources/flex-data-source/FlexCollectionItems.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,62 +9,55 @@ import Foundation
import LithoOperators
import Prelude

open class FlexModelCollectionItem<T, C>: ConcreteFlexCollectionItem<C> where C: UICollectionViewCell {
open class FlexModelCollectionItem<T, C>: ConcreteFlexCollectionItem<C>, Tappable where C: UICollectionViewCell {
open var model: T
open var configurer: (C) -> Void
public var onTap: (() -> Void)?
public var onButtonPressed: (() -> Void)?
public var gestureRecognizer: UIGestureRecognizer?
public var onGesture: ((T, UIGestureRecognizer?) -> Void)?

public init(_ model: T, _ configurer: @escaping (T, C) -> Void) {
self.model = model
self.configurer = model *-> configurer
super.init(identifier: String(describing: C.self))
}

override open func configureCell(_ cell: UICollectionViewCell) {
if let cell = cell as? C {
configurer(cell)
}
}
}

open class FlexTappableModelCollectionItem<T, C>: FlexModelCollectionItem<T, C>, Tappable where C: UICollectionViewCell {
public var onTap: () -> Void = {}

public init(model: T, configurer: @escaping (T, C) -> Void, tap: @escaping (T) -> Void) {
self.onTap = voidCurry(model, tap)
super.init(model, configurer)
self.model = model
self.configurer = model *-> configurer
super.init(identifier: String(describing: C.self))
}
}

open class FlexButtonTappableModelCollectionItem<T, C>: FlexTappableModelCollectionItem<T, C> where C: UICollectionViewCell {
public var onButtonPressed: () -> Void

public init(model: T,
configurer: @escaping (T, C) -> Void,
tap: @escaping (T) -> Void,
buttonPressed: @escaping () -> Void) {
self.onButtonPressed = buttonPressed
super.init(model: model, configurer: configurer, tap: tap)
self.model = model
self.configurer = model *-> configurer
super.init(identifier: String(describing: C.self))
}

public init(model: T,
configurer: @escaping (T, C) -> Void,
tap: @escaping (T) -> Void,
buttonPressed: @escaping (T) -> Void) {
self.onButtonPressed = voidCurry(model, buttonPressed)
super.init(model: model, configurer: configurer, tap: tap)
self.model = model
self.configurer = model *-> configurer
super.init(identifier: String(describing: C.self))
}
}

open class FlexGestureModelCollectionItem<T, C>: FlexModelCollectionItem<T, C> where C: UICollectionViewCell {
public var gestureRecognizer: UIGestureRecognizer?
public var onGesture: ((T, UIGestureRecognizer?) -> Void)?

override open func configureCell(_ cell: UICollectionViewCell) {
if let recognizer = gestureRecognizer {
cell.contentView.removeGestureRecognizer(recognizer)
cell.contentView.addGestureRecognizer(recognizer)
}
super.configureCell(cell)
if let cell = cell as? C {
configurer(cell)
}
}

@objc open func gesturePerformed() {
Expand All @@ -76,7 +69,7 @@ public func modelItem<T, U: UICollectionViewCell>(_ configurer: @escaping (T, U)
return configurer -*> FlexModelCollectionItem.init
}

public func tappableModelItem<T, U: UICollectionViewCell>(_ configurer: @escaping (T, U) -> Void, onTap: @escaping (T) -> Void) -> (T) -> FlexTappableModelCollectionItem<T, U> {
return (configurer, onTap) -**> FlexTappableModelCollectionItem.init
public func tappableModelItem<T, U: UICollectionViewCell>(_ configurer: @escaping (T, U) -> Void, onTap: @escaping (T) -> Void) -> (T) -> FlexModelCollectionItem<T, U> {
return (configurer, onTap) -**> FlexModelCollectionItem.init
}

36 changes: 36 additions & 0 deletions Sources/flex-data-source/FlexCollectionViewModel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//
// FlexCollectionViewModel.swift
// FlexDataSource
//
// Created by Elliot Schrock on 6/14/22.
//

import fuikit
import Combine

open class FlexCollectionViewModel {
open var dataSource: FlexCollectionDataSource { didSet { didSetDataSource() }}
open var delegate: FPUICollectionViewDelegate { didSet { didSetTableDelegate() }}

public var collectionView: UICollectionView? { didSet { configureTableView() }}

public init(_ ds: FlexCollectionDataSource = FlexCollectionDataSource(), _ delegate: FPUICollectionViewDelegate = FPUICollectionViewDelegate()) {
self.dataSource = ds
self.delegate = delegate
}

open func didSetDataSource() { configureTableView() }
open func didSetTableDelegate() { configureTableView() }
open func configureTableView() {
dataSource.collectionView = collectionView
collectionView?.delegate = delegate
}
}

public extension FlexCollectionViewModel {
@available(iOS 13.0, *)
convenience init(_ publisher: AnyPublisher<[FlexCollectionItem], Never>, _ cancelBag: inout Set<AnyCancellable>) {
self.init()
publisher.sink(receiveValue: dataSource.setItems(_:)).store(in: &cancelBag)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@

import UIKit
import fuikit
import Combine

open class FlexDataSource: FPUITableViewDataSource, FlexDataSourceProtocol {

public var tableView: UITableView? {
didSet {
registerCells()
Expand Down Expand Up @@ -44,4 +44,14 @@ open class FlexDataSource: FPUITableViewDataSource, FlexDataSourceProtocol {
let section = FlexDataSourceSection(title: nil, items: items)
self.init(tableView, [section])
}

open func setSections(_ sections: [FlexDataSourceSection]?) {
self.sections = sections
tableView?.reloadData()
}

open func setItems(_ items: [FlexDataSourceItem]?) {
let section = FlexDataSourceSection(title: nil, items: items)
setSections([section])
}
}
Loading