From a240acee2d4d80132d7b0a372644d9edbe7ec9f6 Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Fri, 14 Oct 2016 20:35:18 +0300 Subject: [PATCH 01/28] deprecate action method on TableRow, add on instead --- .../Controllers/NibCellsController.swift | 11 ++++++----- Sources/TableRow.swift | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/Demo/Classes/Presentation/Controllers/NibCellsController.swift b/Demo/Classes/Presentation/Controllers/NibCellsController.swift index 32736a6..544a095 100644 --- a/Demo/Classes/Presentation/Controllers/NibCellsController.swift +++ b/Demo/Classes/Presentation/Controllers/NibCellsController.swift @@ -21,12 +21,13 @@ class NibCellsController: UITableViewController { tableDirector = TableDirector(tableView: tableView) let numbers = [1000, 2000, 3000, 4000, 5000] - - let shouldHighlightAction = TableRowAction(.shouldHighlight) { (_) -> Bool in - return false - } - let rows = numbers.map { TableRow(item: $0, actions: [shouldHighlightAction]) } + let rows = numbers.map { + TableRow(item: $0) + .on(.shouldHighlight) { (_) -> Bool in + return false + } + } tableDirector.append(rows: rows) } diff --git a/Sources/TableRow.swift b/Sources/TableRow.swift index 6cf3738..b05cada 100644 --- a/Sources/TableRow.swift +++ b/Sources/TableRow.swift @@ -107,6 +107,23 @@ open class TableRow: Row where CellType: UITableView // MARK: - actions - + @discardableResult + open func on(_ action: TableRowAction) -> Self { + + actions[action.type.key] = action + return self + } + + @discardableResult + open func on(_ type: TableRowActionType, handler: @escaping (_ data: TableRowActionData) -> T) -> Self { + + actions[type.key] = TableRowAction(type, handler: handler) + return self + } + + // MARK: - deprecated actions - + + @available(*, deprecated, message: "Use 'on' method instead") @discardableResult open func action(_ action: TableRowAction) -> Self { @@ -114,6 +131,7 @@ open class TableRow: Row where CellType: UITableView return self } + @available(*, deprecated, message: "Use 'on' method instead") @discardableResult open func action(_ type: TableRowActionType, handler: @escaping (_ data: TableRowActionData) -> T) -> Self { From 9ae69b71cad00c1bd2e7ee706dfee778be90ab00 Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Fri, 14 Oct 2016 20:56:52 +0300 Subject: [PATCH 02/28] add RowAction protocol --- Sources/TableRow.swift | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/Sources/TableRow.swift b/Sources/TableRow.swift index b05cada..a86b500 100644 --- a/Sources/TableRow.swift +++ b/Sources/TableRow.swift @@ -48,6 +48,36 @@ public protocol Row: RowConfigurable, RowActionable, RowHashable { var defaultHeight: CGFloat? { get } } + + + + + +public protocol RowAction { + + func invokeActionOn(cell: CellType, item: CellType.T, path: IndexPath) -> Any? where CellType: UITableViewCell +} + + + + +open class TableRowActionX: RowAction where ActionCellType: UITableViewCell { + + var handler: ((TableRowActionData) -> Void)? + + public func invokeActionOn(cell: CellType, item: CellType.T, path: IndexPath) -> Any? where CellType: UITableViewCell { + + guard let item = item as? ActionCellType.T else { return nil } + + let x = TableRowActionData(item: item, cell: cell as? ActionCellType, path: path, userInfo: nil) + + handler?(x) + + return nil + } +} + + open class TableRow: Row where CellType: UITableViewCell { open let item: CellType.T From 7f65f0c4e0dce0cdc4c5d6b42a10ad13def102f8 Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Fri, 14 Oct 2016 20:59:13 +0300 Subject: [PATCH 03/28] move protocols to separate file --- Sources/TableKit.swift | 79 ++++++++++++++++++++++++++++++ Sources/TableRow.swift | 42 ---------------- Sources/TableRowAction.swift | 25 +--------- TableKit.xcodeproj/project.pbxproj | 4 ++ 4 files changed, 84 insertions(+), 66 deletions(-) create mode 100644 Sources/TableKit.swift diff --git a/Sources/TableKit.swift b/Sources/TableKit.swift new file mode 100644 index 0000000..1f349b9 --- /dev/null +++ b/Sources/TableKit.swift @@ -0,0 +1,79 @@ +// +// Copyright (c) 2015 Max Sokolov https://twitter.com/max_sokolov +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +import UIKit + +public protocol RowConfigurable { + + func configure(_ cell: UITableViewCell) +} + +public protocol RowActionable { + + var editingActions: [UITableViewRowAction]? { get } + func isEditingAllowed(forIndexPath indexPath: IndexPath) -> Bool + + func invoke(_ action: TableRowActionType, cell: UITableViewCell?, path: IndexPath) -> Any? + func hasAction(_ action: TableRowActionType) -> Bool +} + +public protocol RowHashable { + + var hashValue: Int { get } +} + +public protocol Row: RowConfigurable, RowActionable, RowHashable { + + var reuseIdentifier: String { get } + var cellType: AnyClass { get } + + var estimatedHeight: CGFloat? { get } + var defaultHeight: CGFloat? { get } +} + +public enum TableRowActionType { + + case click + case clickDelete + case select + case deselect + case willSelect + case willDisplay + case shouldHighlight + case height + case canEdit + case configure + case custom(String) + + var key: String { + + switch (self) { + case .custom(let key): + return key + default: + return "_\(self)" + } + } +} + +public protocol RowAction { + + func invokeActionOn(cell: CellType, item: CellType.T, path: IndexPath) -> Any? where CellType: UITableViewCell +} diff --git a/Sources/TableRow.swift b/Sources/TableRow.swift index a86b500..128123c 100644 --- a/Sources/TableRow.swift +++ b/Sources/TableRow.swift @@ -20,47 +20,6 @@ import UIKit -public protocol RowConfigurable { - - func configure(_ cell: UITableViewCell) -} - -public protocol RowActionable { - - var editingActions: [UITableViewRowAction]? { get } - func isEditingAllowed(forIndexPath indexPath: IndexPath) -> Bool - - func invoke(_ action: TableRowActionType, cell: UITableViewCell?, path: IndexPath) -> Any? - func hasAction(_ action: TableRowActionType) -> Bool -} - -public protocol RowHashable { - - var hashValue: Int { get } -} - -public protocol Row: RowConfigurable, RowActionable, RowHashable { - - var reuseIdentifier: String { get } - var cellType: AnyClass { get } - - var estimatedHeight: CGFloat? { get } - var defaultHeight: CGFloat? { get } -} - - - - - - -public protocol RowAction { - - func invokeActionOn(cell: CellType, item: CellType.T, path: IndexPath) -> Any? where CellType: UITableViewCell -} - - - - open class TableRowActionX: RowAction where ActionCellType: UITableViewCell { var handler: ((TableRowActionData) -> Void)? @@ -77,7 +36,6 @@ open class TableRowActionX: RowAction where Ac } } - open class TableRow: Row where CellType: UITableViewCell { open let item: CellType.T diff --git a/Sources/TableRowAction.swift b/Sources/TableRowAction.swift index 2533b6a..9c99d2d 100644 --- a/Sources/TableRowAction.swift +++ b/Sources/TableRowAction.swift @@ -20,30 +20,7 @@ import UIKit -public enum TableRowActionType { - - case click - case clickDelete - case select - case deselect - case willSelect - case willDisplay - case shouldHighlight - case height - case canEdit - case configure - case custom(String) - - var key: String { - - switch (self) { - case .custom(let key): - return key - default: - return "_\(self)" - } - } -} + open class TableRowActionData where CellType: UITableViewCell { diff --git a/TableKit.xcodeproj/project.pbxproj b/TableKit.xcodeproj/project.pbxproj index 458862d..cbd0262 100644 --- a/TableKit.xcodeproj/project.pbxproj +++ b/TableKit.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ 50CF6E6B1D6704FE004746FF /* TableCellRegisterer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50CF6E6A1D6704FE004746FF /* TableCellRegisterer.swift */; }; + 50E858581DB153F500A9AA55 /* TableKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50E858571DB153F500A9AA55 /* TableKit.swift */; }; DA9EA7AF1D0EC2C90021F650 /* ConfigurableCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA9EA7A61D0EC2C90021F650 /* ConfigurableCell.swift */; }; DA9EA7B01D0EC2C90021F650 /* HeightStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA9EA7A71D0EC2C90021F650 /* HeightStrategy.swift */; }; DA9EA7B11D0EC2C90021F650 /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA9EA7A81D0EC2C90021F650 /* Operators.swift */; }; @@ -32,6 +33,7 @@ /* Begin PBXFileReference section */ 50CF6E6A1D6704FE004746FF /* TableCellRegisterer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableCellRegisterer.swift; sourceTree = ""; }; + 50E858571DB153F500A9AA55 /* TableKit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableKit.swift; sourceTree = ""; }; DA9EA7561D0B679A0021F650 /* TableKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TableKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; DA9EA7A61D0EC2C90021F650 /* ConfigurableCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConfigurableCell.swift; sourceTree = ""; }; DA9EA7A71D0EC2C90021F650 /* HeightStrategy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeightStrategy.swift; sourceTree = ""; }; @@ -88,6 +90,7 @@ DA9EA7A51D0EC2B90021F650 /* Sources */ = { isa = PBXGroup; children = ( + 50E858571DB153F500A9AA55 /* TableKit.swift */, DA9EA7AA1D0EC2C90021F650 /* TableDirector.swift */, 50CF6E6A1D6704FE004746FF /* TableCellRegisterer.swift */, DA9EA7AB1D0EC2C90021F650 /* TableRow.swift */, @@ -236,6 +239,7 @@ DA9EA7B21D0EC2C90021F650 /* TableCellAction.swift in Sources */, DA9EA7B11D0EC2C90021F650 /* Operators.swift in Sources */, DA9EA7B41D0EC2C90021F650 /* TableRow.swift in Sources */, + 50E858581DB153F500A9AA55 /* TableKit.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; From 3de586c4f6dd59f5bb6f2b066b80b4ef39daa80e Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Fri, 14 Oct 2016 21:16:21 +0300 Subject: [PATCH 04/28] implement RowAction protocol --- Sources/TableKit.swift | 6 ++++-- Sources/TableRow.swift | 24 ++++-------------------- Sources/TableRowAction.swift | 16 ++++++++-------- 3 files changed, 16 insertions(+), 30 deletions(-) diff --git a/Sources/TableKit.swift b/Sources/TableKit.swift index 1f349b9..eebc57d 100644 --- a/Sources/TableKit.swift +++ b/Sources/TableKit.swift @@ -74,6 +74,8 @@ public enum TableRowActionType { } public protocol RowAction { - - func invokeActionOn(cell: CellType, item: CellType.T, path: IndexPath) -> Any? where CellType: UITableViewCell + + var type: TableRowActionType { get } + + func invokeActionOn(cell: UITableViewCell?, item: Any, path: IndexPath) -> Any? } diff --git a/Sources/TableRow.swift b/Sources/TableRow.swift index 128123c..5135ea9 100644 --- a/Sources/TableRow.swift +++ b/Sources/TableRow.swift @@ -20,26 +20,10 @@ import UIKit -open class TableRowActionX: RowAction where ActionCellType: UITableViewCell { - - var handler: ((TableRowActionData) -> Void)? - - public func invokeActionOn(cell: CellType, item: CellType.T, path: IndexPath) -> Any? where CellType: UITableViewCell { - - guard let item = item as? ActionCellType.T else { return nil } - - let x = TableRowActionData(item: item, cell: cell as? ActionCellType, path: path, userInfo: nil) - - handler?(x) - - return nil - } -} - open class TableRow: Row where CellType: UITableViewCell { open let item: CellType.T - private lazy var actions = [String: TableRowAction]() + private lazy var actions = [String: RowAction]() private(set) open var editingActions: [UITableViewRowAction]? open var hashValue: Int { @@ -62,7 +46,7 @@ open class TableRow: Row where CellType: UITableView return CellType.self } - public init(item: CellType.T, actions: [TableRowAction]? = nil, editingActions: [UITableViewRowAction]? = nil) { + public init(item: CellType.T, actions: [RowAction]? = nil, editingActions: [UITableViewRowAction]? = nil) { self.item = item self.editingActions = editingActions @@ -78,7 +62,7 @@ open class TableRow: Row where CellType: UITableView // MARK: - RowActionable - open func invoke(_ action: TableRowActionType, cell: UITableViewCell?, path: IndexPath) -> Any? { - return actions[action.key]?.invoke(item: item, cell: cell, path: path) + return actions[action.key]?.invokeActionOn(cell: cell, item: item, path: path) } open func hasAction(_ action: TableRowActionType) -> Bool { @@ -96,7 +80,7 @@ open class TableRow: Row where CellType: UITableView // MARK: - actions - @discardableResult - open func on(_ action: TableRowAction) -> Self { + open func on(_ action: RowAction) -> Self { actions[action.type.key] = action return self diff --git a/Sources/TableRowAction.swift b/Sources/TableRowAction.swift index 9c99d2d..1698226 100644 --- a/Sources/TableRowAction.swift +++ b/Sources/TableRowAction.swift @@ -20,8 +20,6 @@ import UIKit - - open class TableRowActionData where CellType: UITableViewCell { open let item: CellType.T @@ -43,18 +41,18 @@ private enum TableRowActionHandler where CellType: U case voidAction((TableRowActionData) -> Void) case action((TableRowActionData) -> Any?) - func invoke(item: CellType.T, cell: UITableViewCell?, path: IndexPath) -> Any? { + func invoke(withActionData actionData: TableRowActionData) -> Any? { switch self { case .voidAction(let handler): - return handler(TableRowActionData(item: item, cell: cell as? CellType, path: path, userInfo: nil)) + return handler(actionData) case .action(let handler): - return handler(TableRowActionData(item: item, cell: cell as? CellType, path: path, userInfo: nil)) + return handler(actionData) } } } -open class TableRowAction where CellType: UITableViewCell { +open class TableRowAction: RowAction where CellType: UITableViewCell { open let type: TableRowActionType private let handler: TableRowActionHandler @@ -71,7 +69,9 @@ open class TableRowAction where CellType: UITableVie self.handler = .action(handler) } - func invoke(item: CellType.T, cell: UITableViewCell?, path: IndexPath) -> Any? { - return handler.invoke(item: item, cell: cell, path: path) + public func invokeActionOn(cell: UITableViewCell?, item: Any, path: IndexPath) -> Any? { + guard let item = item as? CellType.T else { return nil } + + return handler.invoke(withActionData: TableRowActionData(item: item, cell: cell as? CellType, path: path, userInfo: nil)) } } From 3da097f1f18fc4355080b201da9cede35809cbde Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Sat, 15 Oct 2016 01:12:51 +0300 Subject: [PATCH 05/28] support multiple actions with same type --- Sources/TableRow.swift | 30 ++++++++++++++++-------------- Sources/TableRowAction.swift | 3 ++- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/Sources/TableRow.swift b/Sources/TableRow.swift index 5135ea9..bcb0df1 100644 --- a/Sources/TableRow.swift +++ b/Sources/TableRow.swift @@ -23,7 +23,7 @@ import UIKit open class TableRow: Row where CellType: UITableViewCell { open let item: CellType.T - private lazy var actions = [String: RowAction]() + private lazy var actions = [String: [RowAction]]() private(set) open var editingActions: [UITableViewRowAction]? open var hashValue: Int { @@ -46,11 +46,11 @@ open class TableRow: Row where CellType: UITableView return CellType.self } - public init(item: CellType.T, actions: [RowAction]? = nil, editingActions: [UITableViewRowAction]? = nil) { + public init(item: CellType.T, actions: [TableRowAction]? = nil, editingActions: [UITableViewRowAction]? = nil) { self.item = item self.editingActions = editingActions - actions?.forEach { self.actions[$0.type.key] = $0 } + actions?.forEach { on($0) } } // MARK: - RowConfigurable - @@ -62,7 +62,8 @@ open class TableRow: Row where CellType: UITableView // MARK: - RowActionable - open func invoke(_ action: TableRowActionType, cell: UITableViewCell?, path: IndexPath) -> Any? { - return actions[action.key]?.invokeActionOn(cell: cell, item: item, path: path) + + return actions[action.key]?.flatMap({ $0.invokeActionOn(cell: cell, item: item, path: path) }).last } open func hasAction(_ action: TableRowActionType) -> Bool { @@ -80,17 +81,20 @@ open class TableRow: Row where CellType: UITableView // MARK: - actions - @discardableResult - open func on(_ action: RowAction) -> Self { + open func on(_ action: TableRowAction) -> Self { - actions[action.type.key] = action + if actions[action.type.key] == nil { + actions[action.type.key] = [RowAction]() + } + actions[action.type.key]?.append(action) + return self } - + @discardableResult open func on(_ type: TableRowActionType, handler: @escaping (_ data: TableRowActionData) -> T) -> Self { - actions[type.key] = TableRowAction(type, handler: handler) - return self + return on(TableRowAction(type, handler: handler)) } // MARK: - deprecated actions - @@ -98,16 +102,14 @@ open class TableRow: Row where CellType: UITableView @available(*, deprecated, message: "Use 'on' method instead") @discardableResult open func action(_ action: TableRowAction) -> Self { - - actions[action.type.key] = action - return self + + return on(action) } @available(*, deprecated, message: "Use 'on' method instead") @discardableResult open func action(_ type: TableRowActionType, handler: @escaping (_ data: TableRowActionData) -> T) -> Self { - actions[type.key] = TableRowAction(type, handler: handler) - return self + return on(TableRowAction(type, handler: handler)) } } diff --git a/Sources/TableRowAction.swift b/Sources/TableRowAction.swift index 1698226..38607c1 100644 --- a/Sources/TableRowAction.swift +++ b/Sources/TableRowAction.swift @@ -45,7 +45,8 @@ private enum TableRowActionHandler where CellType: U switch self { case .voidAction(let handler): - return handler(actionData) + handler(actionData) + return nil case .action(let handler): return handler(actionData) } From 0af6956d62bcd1b697cf49438b3c157a2b2b5d26 Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Sat, 15 Oct 2016 01:13:41 +0300 Subject: [PATCH 06/28] fix --- Sources/TableDirector.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Sources/TableDirector.swift b/Sources/TableDirector.swift index ecf798a..a0c0e9e 100644 --- a/Sources/TableDirector.swift +++ b/Sources/TableDirector.swift @@ -262,7 +262,9 @@ open class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate { @discardableResult open func clear() -> Self { + heightStrategy?.invalidate() sections.removeAll() + return self } } From c0406136543109aed4c09eba00b240bfd54f957f Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Sat, 15 Oct 2016 01:19:48 +0300 Subject: [PATCH 07/28] add removeAllActions method --- .../Presentation/Controllers/MainController.swift | 9 +++++++-- Sources/TableRow.swift | 5 +++++ Tests/TableKitTests.swift | 2 +- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/Demo/Classes/Presentation/Controllers/MainController.swift b/Demo/Classes/Presentation/Controllers/MainController.swift index 7c0afdd..3cdf176 100644 --- a/Demo/Classes/Presentation/Controllers/MainController.swift +++ b/Demo/Classes/Presentation/Controllers/MainController.swift @@ -34,11 +34,16 @@ class MainController: UIViewController { break } } + + let printClickAction = TableRowAction(.click) { (data) in + + print("click", data.indexPath) + } let rows = [ - TableRow(item: "Autolayout cells", actions: [clickAction]), - TableRow(item: "Nib cells", actions: [clickAction]) + TableRow(item: "Autolayout cells", actions: [clickAction, printClickAction]), + TableRow(item: "Nib cells", actions: [clickAction, printClickAction]) ] // automatically creates a section, also could be used like tableDirector.append(rows: rows) diff --git a/Sources/TableRow.swift b/Sources/TableRow.swift index bcb0df1..67d268f 100644 --- a/Sources/TableRow.swift +++ b/Sources/TableRow.swift @@ -97,6 +97,11 @@ open class TableRow: Row where CellType: UITableView return on(TableRowAction(type, handler: handler)) } + func removeAllActions() { + + actions.removeAll() + } + // MARK: - deprecated actions - @available(*, deprecated, message: "Use 'on' method instead") diff --git a/Tests/TableKitTests.swift b/Tests/TableKitTests.swift index 014cf4d..1ac4b01 100644 --- a/Tests/TableKitTests.swift +++ b/Tests/TableKitTests.swift @@ -171,7 +171,7 @@ class TabletTests: XCTestCase { let expectation = self.expectation(description: "cell action") let row = TableRow(item: TestData(title: "title")) - .action(TableRowAction(.custom(TestTableViewCellOptions.CellAction)) { (data) in + .on(TableRowAction(.custom(TestTableViewCellOptions.CellAction)) { (data) in XCTAssertNotNil(data.cell, "Action data should have a cell") From 5f6de4703a363fe6f6f7a1cb229abd2f757094d2 Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Sat, 15 Oct 2016 01:31:05 +0300 Subject: [PATCH 08/28] add id to action --- Demo/Classes/Presentation/Controllers/MainController.swift | 2 +- Sources/TableKit.swift | 1 + Sources/TableRowAction.swift | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Demo/Classes/Presentation/Controllers/MainController.swift b/Demo/Classes/Presentation/Controllers/MainController.swift index 3cdf176..a8360f4 100644 --- a/Demo/Classes/Presentation/Controllers/MainController.swift +++ b/Demo/Classes/Presentation/Controllers/MainController.swift @@ -25,7 +25,7 @@ class MainController: UIViewController { let clickAction = TableRowAction(.click) { [weak self] (data) in - switch (data.indexPath as NSIndexPath).row { + switch data.indexPath.row { case 0: self?.performSegue(withIdentifier: "autolayoutcells", sender: nil) case 1: diff --git a/Sources/TableKit.swift b/Sources/TableKit.swift index eebc57d..cf3ec49 100644 --- a/Sources/TableKit.swift +++ b/Sources/TableKit.swift @@ -75,6 +75,7 @@ public enum TableRowActionType { public protocol RowAction { + var id: String? { get set } var type: TableRowActionType { get } func invokeActionOn(cell: UITableViewCell?, item: Any, path: IndexPath) -> Any? diff --git a/Sources/TableRowAction.swift b/Sources/TableRowAction.swift index 38607c1..2bf5641 100644 --- a/Sources/TableRowAction.swift +++ b/Sources/TableRowAction.swift @@ -55,6 +55,7 @@ private enum TableRowActionHandler where CellType: U open class TableRowAction: RowAction where CellType: UITableViewCell { + open var id: String? open let type: TableRowActionType private let handler: TableRowActionHandler From b74403e2c62fc99aa3488015bb893af79b3dea8a Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Sat, 15 Oct 2016 11:09:48 +0300 Subject: [PATCH 09/28] add removeAction method --- Sources/TableRow.swift | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Sources/TableRow.swift b/Sources/TableRow.swift index 67d268f..c11eae5 100644 --- a/Sources/TableRow.swift +++ b/Sources/TableRow.swift @@ -56,6 +56,7 @@ open class TableRow: Row where CellType: UITableView // MARK: - RowConfigurable - open func configure(_ cell: UITableViewCell) { + (cell as? CellType)?.configure(with: item) } @@ -67,6 +68,7 @@ open class TableRow: Row where CellType: UITableView } open func hasAction(_ action: TableRowActionType) -> Bool { + return actions[action.key] != nil } @@ -97,11 +99,20 @@ open class TableRow: Row where CellType: UITableView return on(TableRowAction(type, handler: handler)) } - func removeAllActions() { + open func removeAllActions() { actions.removeAll() } + open func removeAction(forActionId actionId: String) { + + for (key, value) in actions { + if let actionIndex = value.index(where: { $0.id == actionId }) { + actions[key]?.remove(at: actionIndex) + } + } + } + // MARK: - deprecated actions - @available(*, deprecated, message: "Use 'on' method instead") From e18c6ef6698a4b29452ed783e8158178a0e42cdd Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Sat, 15 Oct 2016 11:13:54 +0300 Subject: [PATCH 10/28] fixes --- Sources/TableDirector.swift | 4 ++-- Sources/TableKit.swift | 4 ++-- Sources/TableRow.swift | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Sources/TableDirector.swift b/Sources/TableDirector.swift index a0c0e9e..4bdf9c0 100644 --- a/Sources/TableDirector.swift +++ b/Sources/TableDirector.swift @@ -71,7 +71,7 @@ open class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate { @discardableResult open func invoke(action: TableRowActionType, cell: UITableViewCell?, indexPath: IndexPath) -> Any? { - return sections[indexPath.section].rows[indexPath.row].invoke(action, cell: cell, path: indexPath) + return sections[indexPath.section].rows[indexPath.row].invoke(action: action, cell: cell, path: indexPath) } open override func responds(to selector: Selector) -> Bool { @@ -85,7 +85,7 @@ open class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate { // MARK: - Internal - func hasAction(_ action: TableRowActionType, atIndexPath indexPath: IndexPath) -> Bool { - return sections[indexPath.section].rows[indexPath.row].hasAction(action) + return sections[indexPath.section].rows[indexPath.row].has(action: action) } func didReceiveAction(_ notification: Notification) { diff --git a/Sources/TableKit.swift b/Sources/TableKit.swift index cf3ec49..420cceb 100644 --- a/Sources/TableKit.swift +++ b/Sources/TableKit.swift @@ -30,8 +30,8 @@ public protocol RowActionable { var editingActions: [UITableViewRowAction]? { get } func isEditingAllowed(forIndexPath indexPath: IndexPath) -> Bool - func invoke(_ action: TableRowActionType, cell: UITableViewCell?, path: IndexPath) -> Any? - func hasAction(_ action: TableRowActionType) -> Bool + func invoke(action: TableRowActionType, cell: UITableViewCell?, path: IndexPath) -> Any? + func has(action: TableRowActionType) -> Bool } public protocol RowHashable { diff --git a/Sources/TableRow.swift b/Sources/TableRow.swift index c11eae5..5e6b607 100644 --- a/Sources/TableRow.swift +++ b/Sources/TableRow.swift @@ -62,12 +62,12 @@ open class TableRow: Row where CellType: UITableView // MARK: - RowActionable - - open func invoke(_ action: TableRowActionType, cell: UITableViewCell?, path: IndexPath) -> Any? { + open func invoke(action: TableRowActionType, cell: UITableViewCell?, path: IndexPath) -> Any? { return actions[action.key]?.flatMap({ $0.invokeActionOn(cell: cell, item: item, path: path) }).last } - open func hasAction(_ action: TableRowActionType) -> Bool { + open func has(action: TableRowActionType) -> Bool { return actions[action.key] != nil } @@ -75,7 +75,7 @@ open class TableRow: Row where CellType: UITableView open func isEditingAllowed(forIndexPath indexPath: IndexPath) -> Bool { if actions[TableRowActionType.canEdit.key] != nil { - return invoke(.canEdit, cell: nil, path: indexPath) as? Bool ?? false + return invoke(action: .canEdit, cell: nil, path: indexPath) as? Bool ?? false } return editingActions?.isEmpty == false || actions[TableRowActionType.clickDelete.key] != nil } From db6dc40fac452de9c8a1a422b76819d90821f8c2 Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Sat, 15 Oct 2016 12:05:59 +0300 Subject: [PATCH 11/28] make RowHeightCalculator public --- Sources/TableDirector.swift | 10 +++++----- Sources/TableKit.swift | 8 ++++++++ ... => TablePrototypeCellHeightCalculator.swift} | 16 ++++------------ TableKit.xcodeproj/project.pbxproj | 8 ++++---- 4 files changed, 21 insertions(+), 21 deletions(-) rename Sources/{HeightStrategy.swift => TablePrototypeCellHeightCalculator.swift} (87%) diff --git a/Sources/TableDirector.swift b/Sources/TableDirector.swift index 4bdf9c0..665e481 100644 --- a/Sources/TableDirector.swift +++ b/Sources/TableDirector.swift @@ -29,13 +29,13 @@ open class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate { open private(set) var sections = [TableSection]() private weak var scrollDelegate: UIScrollViewDelegate? - private var heightStrategy: CellHeightCalculatable? private var cellRegisterer: TableCellRegisterer? + public var rowHeightCalculator: RowHeightCalculator? open var shouldUsePrototypeCellHeightCalculation: Bool = false { didSet { if shouldUsePrototypeCellHeightCalculation { - heightStrategy = PrototypeHeightStrategy(tableView: tableView) + rowHeightCalculator = TablePrototypeCellHeightCalculator(tableView: tableView) } } } @@ -102,7 +102,7 @@ open class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate { cellRegisterer?.register(cellType: row.cellType, forCellReuseIdentifier: row.reuseIdentifier) - return row.estimatedHeight ?? heightStrategy?.estimatedHeight(row, path: indexPath) ?? UITableViewAutomaticDimension + return row.estimatedHeight ?? rowHeightCalculator?.estimatedHeight(forRow: row, at: indexPath) ?? UITableViewAutomaticDimension } open func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { @@ -111,7 +111,7 @@ open class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate { let rowHeight = invoke(action: .height, cell: nil, indexPath: indexPath) as? CGFloat - return rowHeight ?? row.defaultHeight ?? heightStrategy?.height(row, path: indexPath) ?? UITableViewAutomaticDimension + return rowHeight ?? row.defaultHeight ?? rowHeightCalculator?.height(forRow: row, at: indexPath) ?? UITableViewAutomaticDimension } // MARK: UITableViewDataSource - configuration @@ -262,7 +262,7 @@ open class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate { @discardableResult open func clear() -> Self { - heightStrategy?.invalidate() + rowHeightCalculator?.invalidate() sections.removeAll() return self diff --git a/Sources/TableKit.swift b/Sources/TableKit.swift index 420cceb..656908d 100644 --- a/Sources/TableKit.swift +++ b/Sources/TableKit.swift @@ -80,3 +80,11 @@ public protocol RowAction { func invokeActionOn(cell: UITableViewCell?, item: Any, path: IndexPath) -> Any? } + +public protocol RowHeightCalculator { + + func height(forRow row: Row, at indexPath: IndexPath) -> CGFloat + func estimatedHeight(forRow row: Row, at indexPath: IndexPath) -> CGFloat + + func invalidate() +} diff --git a/Sources/HeightStrategy.swift b/Sources/TablePrototypeCellHeightCalculator.swift similarity index 87% rename from Sources/HeightStrategy.swift rename to Sources/TablePrototypeCellHeightCalculator.swift index 850dde9..8fce9a8 100644 --- a/Sources/HeightStrategy.swift +++ b/Sources/TablePrototypeCellHeightCalculator.swift @@ -20,26 +20,18 @@ import UIKit -public protocol CellHeightCalculatable { - - func height(_ row: Row, path: IndexPath) -> CGFloat - func estimatedHeight(_ row: Row, path: IndexPath) -> CGFloat - - func invalidate() -} - -open class PrototypeHeightStrategy: CellHeightCalculatable { +open class TablePrototypeCellHeightCalculator: RowHeightCalculator { private weak var tableView: UITableView? private var prototypes = [String: UITableViewCell]() private var cachedHeights = [Int: CGFloat]() private var separatorHeight = 1 / UIScreen.main.scale - init(tableView: UITableView?) { + public init(tableView: UITableView?) { self.tableView = tableView } - open func height(_ row: Row, path: IndexPath) -> CGFloat { + open func height(forRow row: Row, at indexPath: IndexPath) -> CGFloat { guard let tableView = tableView else { return 0 } @@ -71,7 +63,7 @@ open class PrototypeHeightStrategy: CellHeightCalculatable { return height } - open func estimatedHeight(_ row: Row, path: IndexPath) -> CGFloat { + open func estimatedHeight(forRow row: Row, at indexPath: IndexPath) -> CGFloat { guard let tableView = tableView else { return 0 } diff --git a/TableKit.xcodeproj/project.pbxproj b/TableKit.xcodeproj/project.pbxproj index cbd0262..c2ace6d 100644 --- a/TableKit.xcodeproj/project.pbxproj +++ b/TableKit.xcodeproj/project.pbxproj @@ -10,7 +10,7 @@ 50CF6E6B1D6704FE004746FF /* TableCellRegisterer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50CF6E6A1D6704FE004746FF /* TableCellRegisterer.swift */; }; 50E858581DB153F500A9AA55 /* TableKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50E858571DB153F500A9AA55 /* TableKit.swift */; }; DA9EA7AF1D0EC2C90021F650 /* ConfigurableCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA9EA7A61D0EC2C90021F650 /* ConfigurableCell.swift */; }; - DA9EA7B01D0EC2C90021F650 /* HeightStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA9EA7A71D0EC2C90021F650 /* HeightStrategy.swift */; }; + DA9EA7B01D0EC2C90021F650 /* TablePrototypeCellHeightCalculator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA9EA7A71D0EC2C90021F650 /* TablePrototypeCellHeightCalculator.swift */; }; DA9EA7B11D0EC2C90021F650 /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA9EA7A81D0EC2C90021F650 /* Operators.swift */; }; DA9EA7B21D0EC2C90021F650 /* TableCellAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA9EA7A91D0EC2C90021F650 /* TableCellAction.swift */; }; DA9EA7B31D0EC2C90021F650 /* TableDirector.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA9EA7AA1D0EC2C90021F650 /* TableDirector.swift */; }; @@ -36,7 +36,7 @@ 50E858571DB153F500A9AA55 /* TableKit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableKit.swift; sourceTree = ""; }; DA9EA7561D0B679A0021F650 /* TableKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TableKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; DA9EA7A61D0EC2C90021F650 /* ConfigurableCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConfigurableCell.swift; sourceTree = ""; }; - DA9EA7A71D0EC2C90021F650 /* HeightStrategy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeightStrategy.swift; sourceTree = ""; }; + DA9EA7A71D0EC2C90021F650 /* TablePrototypeCellHeightCalculator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TablePrototypeCellHeightCalculator.swift; sourceTree = ""; }; DA9EA7A81D0EC2C90021F650 /* Operators.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Operators.swift; sourceTree = ""; }; DA9EA7A91D0EC2C90021F650 /* TableCellAction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableCellAction.swift; sourceTree = ""; }; DA9EA7AA1D0EC2C90021F650 /* TableDirector.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableDirector.swift; sourceTree = ""; }; @@ -97,9 +97,9 @@ DA9EA7AC1D0EC2C90021F650 /* TableRowAction.swift */, DA9EA7AE1D0EC2C90021F650 /* TableSection.swift */, DA9EA7A91D0EC2C90021F650 /* TableCellAction.swift */, + DA9EA7A71D0EC2C90021F650 /* TablePrototypeCellHeightCalculator.swift */, DA9EA7A61D0EC2C90021F650 /* ConfigurableCell.swift */, DA9EA7A81D0EC2C90021F650 /* Operators.swift */, - DA9EA7A71D0EC2C90021F650 /* HeightStrategy.swift */, ); path = Sources; sourceTree = ""; @@ -234,7 +234,7 @@ DA9EA7AF1D0EC2C90021F650 /* ConfigurableCell.swift in Sources */, DA9EA7B31D0EC2C90021F650 /* TableDirector.swift in Sources */, DA9EA7B71D0EC2C90021F650 /* TableSection.swift in Sources */, - DA9EA7B01D0EC2C90021F650 /* HeightStrategy.swift in Sources */, + DA9EA7B01D0EC2C90021F650 /* TablePrototypeCellHeightCalculator.swift in Sources */, DA9EA7B51D0EC2C90021F650 /* TableRowAction.swift in Sources */, DA9EA7B21D0EC2C90021F650 /* TableCellAction.swift in Sources */, DA9EA7B11D0EC2C90021F650 /* Operators.swift in Sources */, From b449e05edcea21ba6274c699eb2a597047f33f45 Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Sat, 15 Oct 2016 12:06:48 +0300 Subject: [PATCH 12/28] fix --- Sources/TableDirector.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Sources/TableDirector.swift b/Sources/TableDirector.swift index 665e481..63de5f7 100644 --- a/Sources/TableDirector.swift +++ b/Sources/TableDirector.swift @@ -36,6 +36,8 @@ open class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate { didSet { if shouldUsePrototypeCellHeightCalculation { rowHeightCalculator = TablePrototypeCellHeightCalculator(tableView: tableView) + } else { + rowHeightCalculator = nil } } } From c3d6f0af603be6f4935d89ce2cb4181a6dbde606 Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Sat, 15 Oct 2016 12:16:25 +0300 Subject: [PATCH 13/28] TableRowActionData -> TableRowActionOptions --- .../Controllers/MainController.swift | 8 ++++---- Sources/TableRow.swift | 4 ++-- Sources/TableRowAction.swift | 18 +++++++++--------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Demo/Classes/Presentation/Controllers/MainController.swift b/Demo/Classes/Presentation/Controllers/MainController.swift index a8360f4..50a244a 100644 --- a/Demo/Classes/Presentation/Controllers/MainController.swift +++ b/Demo/Classes/Presentation/Controllers/MainController.swift @@ -23,9 +23,9 @@ class MainController: UIViewController { title = "TableKit" - let clickAction = TableRowAction(.click) { [weak self] (data) in + let clickAction = TableRowAction(.click) { [weak self] (options) in - switch data.indexPath.row { + switch options.indexPath.row { case 0: self?.performSegue(withIdentifier: "autolayoutcells", sender: nil) case 1: @@ -35,9 +35,9 @@ class MainController: UIViewController { } } - let printClickAction = TableRowAction(.click) { (data) in + let printClickAction = TableRowAction(.click) { (options) in - print("click", data.indexPath) + print("click", options.indexPath) } let rows = [ diff --git a/Sources/TableRow.swift b/Sources/TableRow.swift index 5e6b607..3fbe569 100644 --- a/Sources/TableRow.swift +++ b/Sources/TableRow.swift @@ -94,7 +94,7 @@ open class TableRow: Row where CellType: UITableView } @discardableResult - open func on(_ type: TableRowActionType, handler: @escaping (_ data: TableRowActionData) -> T) -> Self { + open func on(_ type: TableRowActionType, handler: @escaping (_ options: TableRowActionOptions) -> T) -> Self { return on(TableRowAction(type, handler: handler)) } @@ -124,7 +124,7 @@ open class TableRow: Row where CellType: UITableView @available(*, deprecated, message: "Use 'on' method instead") @discardableResult - open func action(_ type: TableRowActionType, handler: @escaping (_ data: TableRowActionData) -> T) -> Self { + open func action(_ type: TableRowActionType, handler: @escaping (_ options: TableRowActionOptions) -> T) -> Self { return on(TableRowAction(type, handler: handler)) } diff --git a/Sources/TableRowAction.swift b/Sources/TableRowAction.swift index 2bf5641..df415d3 100644 --- a/Sources/TableRowAction.swift +++ b/Sources/TableRowAction.swift @@ -20,7 +20,7 @@ import UIKit -open class TableRowActionData where CellType: UITableViewCell { +open class TableRowActionOptions where CellType: UITableViewCell { open let item: CellType.T open let cell: CellType? @@ -38,17 +38,17 @@ open class TableRowActionData where CellType: UITabl private enum TableRowActionHandler where CellType: UITableViewCell { - case voidAction((TableRowActionData) -> Void) - case action((TableRowActionData) -> Any?) + case voidAction((TableRowActionOptions) -> Void) + case action((TableRowActionOptions) -> Any?) - func invoke(withActionData actionData: TableRowActionData) -> Any? { + func invoke(withOptions options: TableRowActionOptions) -> Any? { switch self { case .voidAction(let handler): - handler(actionData) + handler(options) return nil case .action(let handler): - return handler(actionData) + return handler(options) } } } @@ -59,13 +59,13 @@ open class TableRowAction: RowAction where CellType: open let type: TableRowActionType private let handler: TableRowActionHandler - public init(_ type: TableRowActionType, handler: @escaping (_ data: TableRowActionData) -> Void) { + public init(_ type: TableRowActionType, handler: @escaping (_ options: TableRowActionOptions) -> Void) { self.type = type self.handler = .voidAction(handler) } - public init(_ type: TableRowActionType, handler: @escaping (_ data: TableRowActionData) -> T) { + public init(_ type: TableRowActionType, handler: @escaping (_ options: TableRowActionOptions) -> T) { self.type = type self.handler = .action(handler) @@ -74,6 +74,6 @@ open class TableRowAction: RowAction where CellType: public func invokeActionOn(cell: UITableViewCell?, item: Any, path: IndexPath) -> Any? { guard let item = item as? CellType.T else { return nil } - return handler.invoke(withActionData: TableRowActionData(item: item, cell: cell as? CellType, path: path, userInfo: nil)) + return handler.invoke(withOptions: TableRowActionOptions(item: item, cell: cell as? CellType, path: path, userInfo: nil)) } } From becdc205bb0af1d12a5f0c7d880f693d4e69acae Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Sun, 16 Oct 2016 12:22:40 +0300 Subject: [PATCH 14/28] fix --- Sources/TablePrototypeCellHeightCalculator.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/TablePrototypeCellHeightCalculator.swift b/Sources/TablePrototypeCellHeightCalculator.swift index 8fce9a8..0f29a6f 100644 --- a/Sources/TablePrototypeCellHeightCalculator.swift +++ b/Sources/TablePrototypeCellHeightCalculator.swift @@ -22,7 +22,7 @@ import UIKit open class TablePrototypeCellHeightCalculator: RowHeightCalculator { - private weak var tableView: UITableView? + private(set) weak var tableView: UITableView? private var prototypes = [String: UITableViewCell]() private var cachedHeights = [Int: CGFloat]() private var separatorHeight = 1 / UIScreen.main.scale From 8991138f187f939a7455263b0ed2b7a1ff8ec52d Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Sun, 16 Oct 2016 12:35:42 +0300 Subject: [PATCH 15/28] bump readme --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index dfad30d..d08f63e 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Build Status Swift 3.0 compatible Carthage compatible - CocoaPods compatible + CocoaPods compatible Platform iOS License: MIT

@@ -84,13 +84,13 @@ You could have as many rows and sections as you need. It nice to have some actions that related to your cells: ```swift -let action = TableRowAction(.click) { (data) in +let action = TableRowAction(.click) { (options) in // you could access any useful information that relates to the action - // data.cell - StringTableViewCell? - // data.item - String - // data.indexPath - IndexPath + // options.cell - StringTableViewCell? + // options.item - String + // options.indexPath - IndexPath } let row = TableRow(item: "some", actions: [action]) @@ -98,10 +98,10 @@ let row = TableRow(item: "some", actions: [action]) Or, using nice chaining approach: ```swift let row = TableRow(item: "some") - .action(.click) { (data) in + .on(.click) { (options) in } - .action(.shouldHighlight) { (data) -> Bool in + .on(.shouldHighlight) { (options) -> Bool in return false } ``` @@ -126,7 +126,7 @@ class MyTableViewCell: UITableViewCell, ConfigurableCell { ``` And handle them accordingly: ```swift -let myAction = TableRowAction(.custom(MyActions.ButtonClicked)) { (data) in +let myAction = TableRowAction(.custom(MyActions.ButtonClicked)) { (options) in } ``` From a5d8f0874ae44c02e63c08e7261ebe638773268b Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Sun, 16 Oct 2016 12:45:07 +0300 Subject: [PATCH 16/28] support userInfo in custom actions --- Sources/TableDirector.swift | 6 +++--- Sources/TableKit.swift | 4 ++-- Sources/TableRow.swift | 4 ++-- Sources/TableRowAction.swift | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Sources/TableDirector.swift b/Sources/TableDirector.swift index 63de5f7..b306b8b 100644 --- a/Sources/TableDirector.swift +++ b/Sources/TableDirector.swift @@ -72,8 +72,8 @@ open class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate { // MARK: Public @discardableResult - open func invoke(action: TableRowActionType, cell: UITableViewCell?, indexPath: IndexPath) -> Any? { - return sections[indexPath.section].rows[indexPath.row].invoke(action: action, cell: cell, path: indexPath) + open func invoke(action: TableRowActionType, cell: UITableViewCell?, indexPath: IndexPath, userInfo: [AnyHashable: Any]? = nil) -> Any? { + return sections[indexPath.section].rows[indexPath.row].invoke(action: action, cell: cell, path: indexPath, userInfo: userInfo) } open override func responds(to selector: Selector) -> Bool { @@ -93,7 +93,7 @@ open class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate { func didReceiveAction(_ notification: Notification) { guard let action = notification.object as? TableCellAction, let indexPath = tableView?.indexPath(for: action.cell) else { return } - invoke(action: .custom(action.key), cell: action.cell, indexPath: indexPath) + invoke(action: .custom(action.key), cell: action.cell, indexPath: indexPath, userInfo: notification.userInfo) } // MARK: - Height diff --git a/Sources/TableKit.swift b/Sources/TableKit.swift index 656908d..7cb6d6e 100644 --- a/Sources/TableKit.swift +++ b/Sources/TableKit.swift @@ -30,7 +30,7 @@ public protocol RowActionable { var editingActions: [UITableViewRowAction]? { get } func isEditingAllowed(forIndexPath indexPath: IndexPath) -> Bool - func invoke(action: TableRowActionType, cell: UITableViewCell?, path: IndexPath) -> Any? + func invoke(action: TableRowActionType, cell: UITableViewCell?, path: IndexPath, userInfo: [AnyHashable: Any]?) -> Any? func has(action: TableRowActionType) -> Bool } @@ -78,7 +78,7 @@ public protocol RowAction { var id: String? { get set } var type: TableRowActionType { get } - func invokeActionOn(cell: UITableViewCell?, item: Any, path: IndexPath) -> Any? + func invokeActionOn(cell: UITableViewCell?, item: Any, path: IndexPath, userInfo: [AnyHashable: Any]?) -> Any? } public protocol RowHeightCalculator { diff --git a/Sources/TableRow.swift b/Sources/TableRow.swift index 3fbe569..26b7360 100644 --- a/Sources/TableRow.swift +++ b/Sources/TableRow.swift @@ -62,9 +62,9 @@ open class TableRow: Row where CellType: UITableView // MARK: - RowActionable - - open func invoke(action: TableRowActionType, cell: UITableViewCell?, path: IndexPath) -> Any? { + open func invoke(action: TableRowActionType, cell: UITableViewCell?, path: IndexPath, userInfo: [AnyHashable: Any]? = nil) -> Any? { - return actions[action.key]?.flatMap({ $0.invokeActionOn(cell: cell, item: item, path: path) }).last + return actions[action.key]?.flatMap({ $0.invokeActionOn(cell: cell, item: item, path: path, userInfo: userInfo) }).last } open func has(action: TableRowActionType) -> Bool { diff --git a/Sources/TableRowAction.swift b/Sources/TableRowAction.swift index df415d3..9d9be52 100644 --- a/Sources/TableRowAction.swift +++ b/Sources/TableRowAction.swift @@ -71,9 +71,9 @@ open class TableRowAction: RowAction where CellType: self.handler = .action(handler) } - public func invokeActionOn(cell: UITableViewCell?, item: Any, path: IndexPath) -> Any? { + public func invokeActionOn(cell: UITableViewCell?, item: Any, path: IndexPath, userInfo: [AnyHashable: Any]?) -> Any? { guard let item = item as? CellType.T else { return nil } - return handler.invoke(withOptions: TableRowActionOptions(item: item, cell: cell as? CellType, path: path, userInfo: nil)) + return handler.invoke(withOptions: TableRowActionOptions(item: item, cell: cell as? CellType, path: path, userInfo: userInfo)) } } From f794dea7eed6ce7204ea975f27b9455677fe6875 Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Sun, 16 Oct 2016 13:06:47 +0300 Subject: [PATCH 17/28] bump readme --- README.md | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d08f63e..eedfd29 100644 --- a/README.md +++ b/README.md @@ -91,6 +91,7 @@ let action = TableRowAction(.click) { (options) in // options.cell - StringTableViewCell? // options.item - String // options.indexPath - IndexPath + // options.userInfo - [AnyHashable: Any]? } let row = TableRow(item: "some", actions: [action]) @@ -130,6 +131,24 @@ let myAction = TableRowAction(.custom(MyActions.ButtonClicked)) } ``` +## Multiple actions with same type + +It's also possible to use multiple actions with same type: +```swift +let click1 = TableRowAction(.click) { (options) in } +click1.id = "click1" // optional + +let click2 = TableRowAction(.click) { (options) in } +click2.id = "click2" // optional + +let row = TableRow(item: "some", actions: [click1, click2]) +``` +Could be useful in case if you want to separate your logic somehow. Actions will be invoked in order which they were attached. +> If you define multiple actions with same type which also return a value, only last return value will be used for table view. +You could also remove any action by id: +```swift +row.removeAction(forActionId: "action_id") +``` # Advanced @@ -149,7 +168,7 @@ It's enough for most cases. But you may be not happy with this. So you could use ```swift tableDirector.shouldUsePrototypeCellHeightCalculation = true ``` -It does all dirty work with prototypes for you [behind the scene](Sources/HeightStrategy.swift), so you don't have to worry about anything except of your cell configuration: +It does all dirty work with prototypes for you [behind the scene](Sources/TablePrototypeCellHeightCalculator.swift), so you don't have to worry about anything except of your cell configuration: ```swift class ImageTableViewCell: UITableViewCell, ConfigurableCell { From 135bc22804441238e5d982969654d30d0be4fc1e Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Mon, 17 Oct 2016 19:40:07 +0300 Subject: [PATCH 18/28] support any actions on row --- Sources/TableKit.swift | 1 + Sources/TableRow.swift | 18 ++++++++++++------ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/Sources/TableKit.swift b/Sources/TableKit.swift index 7cb6d6e..30681d9 100644 --- a/Sources/TableKit.swift +++ b/Sources/TableKit.swift @@ -30,6 +30,7 @@ public protocol RowActionable { var editingActions: [UITableViewRowAction]? { get } func isEditingAllowed(forIndexPath indexPath: IndexPath) -> Bool + func on(anyAction action: RowAction) -> Self func invoke(action: TableRowActionType, cell: UITableViewCell?, path: IndexPath, userInfo: [AnyHashable: Any]?) -> Any? func has(action: TableRowActionType) -> Bool } diff --git a/Sources/TableRow.swift b/Sources/TableRow.swift index 26b7360..d23c7f2 100644 --- a/Sources/TableRow.swift +++ b/Sources/TableRow.swift @@ -84,13 +84,8 @@ open class TableRow: Row where CellType: UITableView @discardableResult open func on(_ action: TableRowAction) -> Self { - - if actions[action.type.key] == nil { - actions[action.type.key] = [RowAction]() - } - actions[action.type.key]?.append(action) - return self + return on(anyAction: action) } @discardableResult @@ -99,6 +94,17 @@ open class TableRow: Row where CellType: UITableView return on(TableRowAction(type, handler: handler)) } + @discardableResult + open func on(anyAction action: RowAction) -> Self { + + if actions[action.type.key] == nil { + actions[action.type.key] = [RowAction]() + } + actions[action.type.key]?.append(action) + + return self + } + open func removeAllActions() { actions.removeAll() From 162aee003316116744caabd1e1e43c9679ace263 Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Tue, 18 Oct 2016 20:44:44 +0300 Subject: [PATCH 19/28] add any action --- Sources/TableRowAnyAction.swift | 30 ++++++++++++++++++++++++++++++ TableKit.xcodeproj/project.pbxproj | 4 ++++ 2 files changed, 34 insertions(+) create mode 100644 Sources/TableRowAnyAction.swift diff --git a/Sources/TableRowAnyAction.swift b/Sources/TableRowAnyAction.swift new file mode 100644 index 0000000..85515ec --- /dev/null +++ b/Sources/TableRowAnyAction.swift @@ -0,0 +1,30 @@ +// +// TableRowAnyAction.swift +// TableKit +// +// Created by Max Sokolov on 18/10/16. +// Copyright © 2016 Max Sokolov. All rights reserved. +// + +import UIKit + +open class TableRowAnyActionOptions { + + +} + +open class TableRowAnyAction { + + open var id: String? + open let type: TableRowActionType + + init(_ type: TableRowActionType, handler: @escaping () -> ()) { + + self.type = type + } + + func invoke(cell: UITableViewCell?, item: Any, path: IndexPath, userInfo: [AnyHashable: Any]?) -> Any? { + + return nil + } +} diff --git a/TableKit.xcodeproj/project.pbxproj b/TableKit.xcodeproj/project.pbxproj index c2ace6d..05181b0 100644 --- a/TableKit.xcodeproj/project.pbxproj +++ b/TableKit.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 50826A001DB694CF002AABB5 /* TableRowAnyAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 508269FF1DB694CF002AABB5 /* TableRowAnyAction.swift */; }; 50CF6E6B1D6704FE004746FF /* TableCellRegisterer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50CF6E6A1D6704FE004746FF /* TableCellRegisterer.swift */; }; 50E858581DB153F500A9AA55 /* TableKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50E858571DB153F500A9AA55 /* TableKit.swift */; }; DA9EA7AF1D0EC2C90021F650 /* ConfigurableCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA9EA7A61D0EC2C90021F650 /* ConfigurableCell.swift */; }; @@ -32,6 +33,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 508269FF1DB694CF002AABB5 /* TableRowAnyAction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableRowAnyAction.swift; sourceTree = ""; }; 50CF6E6A1D6704FE004746FF /* TableCellRegisterer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableCellRegisterer.swift; sourceTree = ""; }; 50E858571DB153F500A9AA55 /* TableKit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableKit.swift; sourceTree = ""; }; DA9EA7561D0B679A0021F650 /* TableKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TableKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -94,6 +96,7 @@ DA9EA7AA1D0EC2C90021F650 /* TableDirector.swift */, 50CF6E6A1D6704FE004746FF /* TableCellRegisterer.swift */, DA9EA7AB1D0EC2C90021F650 /* TableRow.swift */, + 508269FF1DB694CF002AABB5 /* TableRowAnyAction.swift */, DA9EA7AC1D0EC2C90021F650 /* TableRowAction.swift */, DA9EA7AE1D0EC2C90021F650 /* TableSection.swift */, DA9EA7A91D0EC2C90021F650 /* TableCellAction.swift */, @@ -237,6 +240,7 @@ DA9EA7B01D0EC2C90021F650 /* TablePrototypeCellHeightCalculator.swift in Sources */, DA9EA7B51D0EC2C90021F650 /* TableRowAction.swift in Sources */, DA9EA7B21D0EC2C90021F650 /* TableCellAction.swift in Sources */, + 50826A001DB694CF002AABB5 /* TableRowAnyAction.swift in Sources */, DA9EA7B11D0EC2C90021F650 /* Operators.swift in Sources */, DA9EA7B41D0EC2C90021F650 /* TableRow.swift in Sources */, 50E858581DB153F500A9AA55 /* TableKit.swift in Sources */, From 1eed11abbf4f2b87a9bd49aee24fd51c2a0482cf Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Wed, 19 Oct 2016 01:06:10 +0300 Subject: [PATCH 20/28] remove any action --- Sources/TableCellAction.swift | 4 ---- Sources/TableKit.swift | 15 +++++---------- Sources/TableRow.swift | 20 +++++++------------- Sources/TableRowAction.swift | 2 +- Sources/TableRowAnyAction.swift | 30 ------------------------------ TableKit.xcodeproj/project.pbxproj | 4 ---- 6 files changed, 13 insertions(+), 62 deletions(-) delete mode 100644 Sources/TableRowAnyAction.swift diff --git a/Sources/TableCellAction.swift b/Sources/TableCellAction.swift index 0e30413..b962dab 100644 --- a/Sources/TableCellAction.swift +++ b/Sources/TableCellAction.swift @@ -20,10 +20,6 @@ import UIKit -struct TableKitNotifications { - static let CellAction = "TableKitNotificationsCellAction" -} - /** A custom action that you can trigger from your cell. You can easily catch actions using a chaining manner with your row. diff --git a/Sources/TableKit.swift b/Sources/TableKit.swift index 30681d9..bff0ef4 100644 --- a/Sources/TableKit.swift +++ b/Sources/TableKit.swift @@ -20,6 +20,10 @@ import UIKit +struct TableKitNotifications { + static let CellAction = "TableKitNotificationsCellAction" +} + public protocol RowConfigurable { func configure(_ cell: UITableViewCell) @@ -29,8 +33,7 @@ public protocol RowActionable { var editingActions: [UITableViewRowAction]? { get } func isEditingAllowed(forIndexPath indexPath: IndexPath) -> Bool - - func on(anyAction action: RowAction) -> Self + func invoke(action: TableRowActionType, cell: UITableViewCell?, path: IndexPath, userInfo: [AnyHashable: Any]?) -> Any? func has(action: TableRowActionType) -> Bool } @@ -74,14 +77,6 @@ public enum TableRowActionType { } } -public protocol RowAction { - - var id: String? { get set } - var type: TableRowActionType { get } - - func invokeActionOn(cell: UITableViewCell?, item: Any, path: IndexPath, userInfo: [AnyHashable: Any]?) -> Any? -} - public protocol RowHeightCalculator { func height(forRow row: Row, at indexPath: IndexPath) -> CGFloat diff --git a/Sources/TableRow.swift b/Sources/TableRow.swift index d23c7f2..631768c 100644 --- a/Sources/TableRow.swift +++ b/Sources/TableRow.swift @@ -23,7 +23,7 @@ import UIKit open class TableRow: Row where CellType: UITableViewCell { open let item: CellType.T - private lazy var actions = [String: [RowAction]]() + private lazy var actions = [String: [TableRowAction]]() private(set) open var editingActions: [UITableViewRowAction]? open var hashValue: Int { @@ -85,7 +85,12 @@ open class TableRow: Row where CellType: UITableView @discardableResult open func on(_ action: TableRowAction) -> Self { - return on(anyAction: action) + if actions[action.type.key] == nil { + actions[action.type.key] = [TableRowAction]() + } + actions[action.type.key]?.append(action) + + return self } @discardableResult @@ -93,18 +98,7 @@ open class TableRow: Row where CellType: UITableView return on(TableRowAction(type, handler: handler)) } - - @discardableResult - open func on(anyAction action: RowAction) -> Self { - if actions[action.type.key] == nil { - actions[action.type.key] = [RowAction]() - } - actions[action.type.key]?.append(action) - - return self - } - open func removeAllActions() { actions.removeAll() diff --git a/Sources/TableRowAction.swift b/Sources/TableRowAction.swift index 9d9be52..ad92bb4 100644 --- a/Sources/TableRowAction.swift +++ b/Sources/TableRowAction.swift @@ -53,7 +53,7 @@ private enum TableRowActionHandler where CellType: U } } -open class TableRowAction: RowAction where CellType: UITableViewCell { +open class TableRowAction where CellType: UITableViewCell { open var id: String? open let type: TableRowActionType diff --git a/Sources/TableRowAnyAction.swift b/Sources/TableRowAnyAction.swift deleted file mode 100644 index 85515ec..0000000 --- a/Sources/TableRowAnyAction.swift +++ /dev/null @@ -1,30 +0,0 @@ -// -// TableRowAnyAction.swift -// TableKit -// -// Created by Max Sokolov on 18/10/16. -// Copyright © 2016 Max Sokolov. All rights reserved. -// - -import UIKit - -open class TableRowAnyActionOptions { - - -} - -open class TableRowAnyAction { - - open var id: String? - open let type: TableRowActionType - - init(_ type: TableRowActionType, handler: @escaping () -> ()) { - - self.type = type - } - - func invoke(cell: UITableViewCell?, item: Any, path: IndexPath, userInfo: [AnyHashable: Any]?) -> Any? { - - return nil - } -} diff --git a/TableKit.xcodeproj/project.pbxproj b/TableKit.xcodeproj/project.pbxproj index 05181b0..c2ace6d 100644 --- a/TableKit.xcodeproj/project.pbxproj +++ b/TableKit.xcodeproj/project.pbxproj @@ -7,7 +7,6 @@ objects = { /* Begin PBXBuildFile section */ - 50826A001DB694CF002AABB5 /* TableRowAnyAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 508269FF1DB694CF002AABB5 /* TableRowAnyAction.swift */; }; 50CF6E6B1D6704FE004746FF /* TableCellRegisterer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50CF6E6A1D6704FE004746FF /* TableCellRegisterer.swift */; }; 50E858581DB153F500A9AA55 /* TableKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50E858571DB153F500A9AA55 /* TableKit.swift */; }; DA9EA7AF1D0EC2C90021F650 /* ConfigurableCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA9EA7A61D0EC2C90021F650 /* ConfigurableCell.swift */; }; @@ -33,7 +32,6 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 508269FF1DB694CF002AABB5 /* TableRowAnyAction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableRowAnyAction.swift; sourceTree = ""; }; 50CF6E6A1D6704FE004746FF /* TableCellRegisterer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableCellRegisterer.swift; sourceTree = ""; }; 50E858571DB153F500A9AA55 /* TableKit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableKit.swift; sourceTree = ""; }; DA9EA7561D0B679A0021F650 /* TableKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TableKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -96,7 +94,6 @@ DA9EA7AA1D0EC2C90021F650 /* TableDirector.swift */, 50CF6E6A1D6704FE004746FF /* TableCellRegisterer.swift */, DA9EA7AB1D0EC2C90021F650 /* TableRow.swift */, - 508269FF1DB694CF002AABB5 /* TableRowAnyAction.swift */, DA9EA7AC1D0EC2C90021F650 /* TableRowAction.swift */, DA9EA7AE1D0EC2C90021F650 /* TableSection.swift */, DA9EA7A91D0EC2C90021F650 /* TableCellAction.swift */, @@ -240,7 +237,6 @@ DA9EA7B01D0EC2C90021F650 /* TablePrototypeCellHeightCalculator.swift in Sources */, DA9EA7B51D0EC2C90021F650 /* TableRowAction.swift in Sources */, DA9EA7B21D0EC2C90021F650 /* TableCellAction.swift in Sources */, - 50826A001DB694CF002AABB5 /* TableRowAnyAction.swift in Sources */, DA9EA7B11D0EC2C90021F650 /* Operators.swift in Sources */, DA9EA7B41D0EC2C90021F650 /* TableRow.swift in Sources */, 50E858581DB153F500A9AA55 /* TableKit.swift in Sources */, From 28f6a60d61f3954e63c42d5e7fab4d3f9d75c446 Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Wed, 19 Oct 2016 01:13:21 +0300 Subject: [PATCH 21/28] bump readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index eedfd29..22565d4 100644 --- a/README.md +++ b/README.md @@ -145,6 +145,7 @@ let row = TableRow(item: "some", actions: [click1, click2]) ``` Could be useful in case if you want to separate your logic somehow. Actions will be invoked in order which they were attached. > If you define multiple actions with same type which also return a value, only last return value will be used for table view. + You could also remove any action by id: ```swift row.removeAction(forActionId: "action_id") From ecc90b1db80e5f9191a14e7078bab15b0c780e73 Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Wed, 19 Oct 2016 01:19:05 +0300 Subject: [PATCH 22/28] bump changelog --- CHANGELOG.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b60b00..4718083 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,13 @@ All notable changes to this project will be documented in this file. -## [2.0.0](https://github.com/maxsokolov/TableKit/releases/tag/1.4.0) -Released on 2016-09-06. Breaking changes in 2.0.0: +## [2.1.0](https://github.com/maxsokolov/TableKit/releases/tag/1.4.0) +Released on 2016-10-19. +- `action` method was deprecated on TableRow. Use `on` instead. +- Support multiple actions with same type on row. + +## [2.0.0](https://github.com/maxsokolov/TableKit/releases/tag/2.0.0) +Released on 2016-10-06. Breaking changes in 2.0.0:
The signatures of `TableRow` and `TableRowAction` classes were changed from ```swift let action = TableRowAction(.click) { (data) in From b307b2d809547343f23a2686446de43c90f81d80 Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Wed, 19 Oct 2016 01:20:05 +0300 Subject: [PATCH 23/28] bump podspec --- TableKit.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TableKit.podspec b/TableKit.podspec index 1af280b..557a116 100644 --- a/TableKit.podspec +++ b/TableKit.podspec @@ -2,7 +2,7 @@ Pod::Spec.new do |s| s.name = 'TableKit' s.module_name = 'TableKit' - s.version = '2.0.0' + s.version = '2.1.0' s.homepage = 'https://github.com/maxsokolov/TableKit' s.summary = 'Type-safe declarative table views with Swift.' From f19b63799967c999045f276348834f2a5c28642b Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Thu, 20 Oct 2016 12:13:30 +0300 Subject: [PATCH 24/28] deprecate some methods --- Sources/TableDirector.swift | 13 +++++++++++-- Sources/TableSection.swift | 7 +++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/Sources/TableDirector.swift b/Sources/TableDirector.swift index b306b8b..4ea3da6 100644 --- a/Sources/TableDirector.swift +++ b/Sources/TableDirector.swift @@ -254,8 +254,7 @@ open class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate { return self } - @discardableResult - open func delete(index: Int) -> Self { + open func delete(sectionAt index: Int) -> Self { sections.remove(at: index) return self @@ -269,4 +268,14 @@ open class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate { return self } + + // MARK: - deprecated methods - + + @available(*, deprecated, message: "Use 'delete(sectionAt:)' method instead") + @discardableResult + open func delete(index: Int) -> Self { + + sections.remove(at: index) + return self + } } diff --git a/Sources/TableSection.swift b/Sources/TableSection.swift index 127ee0e..273701e 100644 --- a/Sources/TableSection.swift +++ b/Sources/TableSection.swift @@ -88,6 +88,13 @@ open class TableSection { rows[index] = row } + open func delete(rowAt index: Int) { + rows.remove(at: index) + } + + // MARK: - deprecated methods - + + @available(*, deprecated, message: "Use 'delete(rowAt:)' method instead") open func delete(index: Int) { rows.remove(at: index) } From 0f8d0db84ec7c59bce0f3167b62127e3ac5d81c7 Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Thu, 20 Oct 2016 19:33:33 +0300 Subject: [PATCH 25/28] automatic cell registration improvements --- Sources/TableDirector.swift | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/Sources/TableDirector.swift b/Sources/TableDirector.swift index 4ea3da6..cd45ef5 100644 --- a/Sources/TableDirector.swift +++ b/Sources/TableDirector.swift @@ -31,7 +31,7 @@ open class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate { private weak var scrollDelegate: UIScrollViewDelegate? private var cellRegisterer: TableCellRegisterer? public var rowHeightCalculator: RowHeightCalculator? - + open var shouldUsePrototypeCellHeightCalculation: Bool = false { didSet { if shouldUsePrototypeCellHeightCalculation { @@ -52,7 +52,7 @@ open class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate { if shouldUseAutomaticCellRegistration { self.cellRegisterer = TableCellRegisterer(tableView: tableView) } - + self.scrollDelegate = scrollDelegate self.tableView = tableView self.tableView?.delegate = self @@ -99,17 +99,18 @@ open class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate { // MARK: - Height open func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat { - + let row = sections[indexPath.section].rows[indexPath.row] - - cellRegisterer?.register(cellType: row.cellType, forCellReuseIdentifier: row.reuseIdentifier) - return row.estimatedHeight ?? rowHeightCalculator?.estimatedHeight(forRow: row, at: indexPath) ?? UITableViewAutomaticDimension } open func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { let row = sections[indexPath.section].rows[indexPath.row] + + if shouldUsePrototypeCellHeightCalculation { + cellRegisterer?.register(cellType: row.cellType, forCellReuseIdentifier: row.reuseIdentifier) + } let rowHeight = invoke(action: .height, cell: nil, indexPath: indexPath) as? CGFloat @@ -129,6 +130,9 @@ open class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate { open func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let row = sections[indexPath.section].rows[indexPath.row] + + cellRegisterer?.register(cellType: row.cellType, forCellReuseIdentifier: row.reuseIdentifier) + let cell = tableView.dequeueReusableCell(withIdentifier: row.reuseIdentifier, for: indexPath) if cell.frame.size.width != tableView.frame.size.width { From 443b8aaa621d1d65432a31db02d8ec3d5735e7ff Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Fri, 21 Oct 2016 00:52:18 +0300 Subject: [PATCH 26/28] fix table header footer section height --- Sources/TableDirector.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/TableDirector.swift b/Sources/TableDirector.swift index cd45ef5..24dfeb5 100644 --- a/Sources/TableDirector.swift +++ b/Sources/TableDirector.swift @@ -169,13 +169,13 @@ open class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate { open func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { let section = sections[section] - return section.headerHeight ?? section.headerView?.frame.size.height ?? 0 + return section.headerHeight ?? section.headerView?.frame.size.height ?? UITableViewAutomaticDimension } open func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat { let section = sections[section] - return section.footerHeight ?? section.footerView?.frame.size.height ?? 0 + return section.footerHeight ?? section.footerView?.frame.size.height ?? UITableViewAutomaticDimension } // MARK: UITableViewDelegate - actions From d5d785218ac75a71c5a5fdd5f30aba6f9c722e4f Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Fri, 21 Oct 2016 01:35:27 +0300 Subject: [PATCH 27/28] improve custom action init --- Sources/TableRowAction.swift | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Sources/TableRowAction.swift b/Sources/TableRowAction.swift index ad92bb4..40760cb 100644 --- a/Sources/TableRowAction.swift +++ b/Sources/TableRowAction.swift @@ -65,6 +65,12 @@ open class TableRowAction where CellType: UITableVie self.handler = .voidAction(handler) } + public init(_ key: String, handler: @escaping (_ options: TableRowActionOptions) -> Void) { + + self.type = .custom(key) + self.handler = .voidAction(handler) + } + public init(_ type: TableRowActionType, handler: @escaping (_ options: TableRowActionOptions) -> T) { self.type = type From e74fee3653ba56aff93e558c17ea9f029019de69 Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Sun, 23 Oct 2016 12:46:46 +0300 Subject: [PATCH 28/28] bump changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4718083..1a8e65c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ All notable changes to this project will be documented in this file. Released on 2016-10-19. - `action` method was deprecated on TableRow. Use `on` instead. - Support multiple actions with same type on row. +- You could now build your own cell height calculating strategy. See [TablePrototypeCellHeightCalculator](Sources/TablePrototypeCellHeightCalculator.swift). +- Default distance between sections changed to `UITableViewAutomaticDimension`. You can customize it, see [TableSection](Sources/TableSection.swift) ## [2.0.0](https://github.com/maxsokolov/TableKit/releases/tag/2.0.0) Released on 2016-10-06. Breaking changes in 2.0.0: