Skip to content
Merged
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
8 changes: 7 additions & 1 deletion FunctionalTableData/CellActions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public struct CellActions {
public typealias CanSelectCallback = (Bool) -> Void
public typealias CanSelectAction = (_ canSelect: @escaping CanSelectCallback) -> Void
public typealias SelectionAction = (_ sender: UIView) -> SelectionState
public typealias DeselectionAction = (_ sender: UIView) -> SelectionState
public typealias CanPerformAction = (_ selector: Selector) -> Bool
public typealias VisibilityAction = (_ cell: UIView, _ visible: Bool) -> Void
/// Closure type that is executed when the user 3D-touches on a cell
Expand All @@ -32,6 +33,8 @@ public struct CellActions {
public let canSelectAction: CanSelectAction?
/// The action to perform when the cell is selected
public let selectionAction: SelectionAction?
/// The action to perform when the cell is deselected
public let deselectionAction: SelectionAction?
/// All the available row actions this cell can perform. See [UITableViewRowAction](https://developer.apple.com/documentation/uikit/uitableviewrowaction) for more info.
public let rowActions: [UITableViewRowAction]?
/// Indicates if the cell can perform a given action.
Expand All @@ -45,13 +48,15 @@ public struct CellActions {

public init(canSelectAction: CanSelectAction? = nil,
selectionAction: SelectionAction? = nil,
deselectionAction: DeselectionAction? = nil,
rowActions: [UITableViewRowAction]? = nil,
canPerformAction: CanPerformAction? = nil,
canBeMoved: Bool = false,
visibilityAction: VisibilityAction? = nil,
previewingViewControllerAction: PreviewingViewControllerAction? = nil) {
self.canSelectAction = canSelectAction
self.selectionAction = selectionAction
self.deselectionAction = deselectionAction
self.rowActions = rowActions
self.canPerformAction = canPerformAction
self.canBeMoved = canBeMoved
Expand All @@ -61,6 +66,7 @@ public struct CellActions {

public init(canSelectAction: CanSelectAction? = nil,
selectionAction: SelectionAction? = nil,
deselectionAction: DeselectionAction? = nil,
rowActions: [UITableViewRowAction]? = nil,
canPerformAction: CanPerformAction? = nil,
canBeMoved: Bool = false,
Expand All @@ -70,6 +76,6 @@ public struct CellActions {
previewingContext.sourceRect = previewingContext.sourceView.convert(cell.bounds, from: cell)
return previewingViewControllerAction()
}
self.init(canSelectAction: canSelectAction, selectionAction: selectionAction, rowActions: rowActions, canPerformAction: canPerformAction, canBeMoved: canBeMoved, visibilityAction: visibilityAction, previewingViewControllerAction: wrappedPreviewingViewControllerAction)
self.init(canSelectAction: canSelectAction, selectionAction: selectionAction, deselectionAction: deselectionAction, rowActions: rowActions, canPerformAction: canPerformAction, canBeMoved: canBeMoved, visibilityAction: visibilityAction, previewingViewControllerAction: wrappedPreviewingViewControllerAction)
}
}
16 changes: 14 additions & 2 deletions FunctionalTableData/CollectionView/FunctionalCollectionData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -467,10 +467,10 @@ extension FunctionalCollectionData: UICollectionViewDataSource {

extension FunctionalCollectionData: UICollectionViewDelegate {
public func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {
guard let indexPathsForSelectedItems = collectionView.indexPathsForSelectedItems else { return true }
guard let indexPathsForSelectedItems = collectionView.indexPathsForSelectedItems, !collectionView.allowsMultipleSelection else { return true }
return indexPathsForSelectedItems.contains(indexPath) == false
}

public func collectionView(_ collectionView: UICollectionView, shouldHighlightItemAt indexPath: IndexPath) -> Bool {
return sections[indexPath]?.actions.selectionAction != nil
}
Expand All @@ -486,6 +486,18 @@ extension FunctionalCollectionData: UICollectionViewDelegate {
}
}
}

public func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
guard let cell = collectionView.cellForItem(at: indexPath) else { return }
let cellConfig = sections[indexPath]

let selectionState = cellConfig?.actions.deselectionAction?(cell) ?? .deselected
if selectionState == .selected {
DispatchQueue.main.async {
collectionView.selectItem(at: indexPath, animated: true, scrollPosition: [])
}
}
}

public func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
guard indexPath.section < sections.count else { return }
Expand Down
24 changes: 19 additions & 5 deletions FunctionalTableData/TableView/FunctionalTableData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ public class FunctionalTableData: NSObject {
completion?()
}
}

/// Populates the table with the specified sections, and asynchronously updates the table view to reflect the cells and sections that have changed.
///
/// - Parameters:
Expand Down Expand Up @@ -616,12 +616,14 @@ extension FunctionalTableData: UITableViewDelegate {
}
if selected {
selectedCell.setHighlighted(false, animated: false)
tableView.selectRow(at: indexPath, animated: false, scrollPosition: .none)
if selectionAction(selectedCell) == .deselected {

if selectionAction(selectedCell) == .selected {
tableView.selectRow(at: indexPath, animated: false, scrollPosition: .none)
} else {
tableView.deselectRow(at: indexPath, animated: false)
}
if let currentSelection = currentSelection {

if !tableView.allowsMultipleSelection, let currentSelection = currentSelection {
tableView.cellForRow(at: currentSelection)?.setHighlighted(false, animated: false)
tableView.deselectRow(at: currentSelection, animated: false)
}
Expand Down Expand Up @@ -650,6 +652,18 @@ extension FunctionalTableData: UITableViewDelegate {
}
}
}

public func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
guard let cell = tableView.cellForRow(at: indexPath) else { return }
let cellConfig = sections[indexPath]

let selectionState = cellConfig?.actions.deselectionAction?(cell) ?? .deselected
if selectionState == .selected {
DispatchQueue.main.async {
tableView.selectRow(at: indexPath, animated: true, scrollPosition: .none)
}
}
}

public func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
guard indexPath.section < sections.count else { return }
Expand Down
9 changes: 9 additions & 0 deletions FunctionalTableDataDemo/CollectionExampleController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,15 @@ class CollectionExampleController: UICollectionViewController {
return LabelCell(
key: "id-\(index)",
style: CellStyle(backgroundColor: .lightGray),
actions: CellActions(
selectionAction: { (view) -> CellActions.SelectionState in
print("\(item) is being selected")
return .selected
},
deselectionAction: { (view) -> CellActions.SelectionState in
print("\(item) is being deselected")
return .deselected
}),
state: LabelState(text: item),
cellUpdater: LabelState.updateView)
}
Expand Down
9 changes: 9 additions & 0 deletions FunctionalTableDataDemo/TableExampleController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@ class TableExampleController: UITableViewController {
let rows: [CellConfigType] = items.enumerated().map { index, item in
return LabelCell(
key: "id-\(index)",
actions: CellActions(
selectionAction: { (view) -> CellActions.SelectionState in
print("\(item) is being selected")
return .selected
},
deselectionAction: { (view) -> CellActions.SelectionState in
print("\(item) is being deselected")
return .deselected
}),
state: LabelState(text: item),
cellUpdater: LabelState.updateView)
}
Expand Down