From 7d9d6ff60ba34e8dbba07572fea1bd5293938286 Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Sat, 16 Apr 2016 22:48:46 +0300 Subject: [PATCH 01/16] remove useless code, add gitignore --- .gitignore | 39 ++++++++++++++++++ .../UserInterfaceState.xcuserstate | Bin 17148 -> 0 bytes Tablet/TableDirector.swift | 6 +-- Tablet/TableSectionBuilder.swift | 8 +--- Tests/TabletTests.swift | 2 +- 5 files changed, 44 insertions(+), 11 deletions(-) create mode 100755 .gitignore delete mode 100644 Tablet.xcworkspace/xcuserdata/maxsokolov.xcuserdatad/UserInterfaceState.xcuserstate diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000..222e8ec --- /dev/null +++ b/.gitignore @@ -0,0 +1,39 @@ +# Mac OS X +.DS_Store + +# Xcode + +## Build generated +build/ +DerivedData + +## Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata + +## Other +*.xccheckout +*.moved-aside +*.xcuserstate +*.xcscmblueprint + +## Obj-C/Swift specific +*.hmap +*.ipa + +## Playgrounds +timeline.xctimeline +playground.xcworkspace + +# Swift Package Manager +.build/ + +# Carthage +Carthage/Build diff --git a/Tablet.xcworkspace/xcuserdata/maxsokolov.xcuserdatad/UserInterfaceState.xcuserstate b/Tablet.xcworkspace/xcuserdata/maxsokolov.xcuserdatad/UserInterfaceState.xcuserstate deleted file mode 100644 index 0ab37795a72c0fc93aeaf39338dc35bab879a33f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17148 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 CGFloat { - return sections[section].headerHeight + return sections[section].headerView?.frame.size.height ?? UITableViewAutomaticDimension } - + func tableView(tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat { - return sections[section].footerHeight + return sections[section].footerView?.frame.size.height ?? UITableViewAutomaticDimension } } diff --git a/Tablet/TableSectionBuilder.swift b/Tablet/TableSectionBuilder.swift index 30a532e..4bb0d68 100644 --- a/Tablet/TableSectionBuilder.swift +++ b/Tablet/TableSectionBuilder.swift @@ -34,10 +34,7 @@ public class TableSectionBuilder { public var footerTitle: String? public var headerView: UIView? - public var headerHeight: CGFloat = UITableViewAutomaticDimension - public var footerView: UIView? - public var footerHeight: CGFloat = UITableViewAutomaticDimension /// A total number of rows in section of each row builder. public var numberOfRowsInSection: Int { @@ -54,13 +51,10 @@ public class TableSectionBuilder { } } - public init(headerView: UIView? = nil, headerHeight: CGFloat = UITableViewAutomaticDimension, footerView: UIView? = nil, footerHeight: CGFloat = UITableViewAutomaticDimension) { + public init(headerView: UIView? = nil, footerView: UIView? = nil) { self.headerView = headerView - self.headerHeight = headerHeight - self.footerView = footerView - self.footerHeight = footerHeight } // MARK: Public diff --git a/Tests/TabletTests.swift b/Tests/TabletTests.swift index 2d9136e..0cbe395 100644 --- a/Tests/TabletTests.swift +++ b/Tests/TabletTests.swift @@ -157,7 +157,7 @@ class TabletTests: XCTestCase { let sectionHeaderView = UIView() let sectionFooterView = UIView() - let section = TableSectionBuilder(headerView: sectionHeaderView, headerHeight: 44, footerView: sectionFooterView, footerHeight: 44) + let section = TableSectionBuilder(headerView: sectionHeaderView, footerView: sectionFooterView) section += row testController.view.hidden = false From ef384cb0f1e7a4be32efca7f80f8268816004f66 Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Sun, 17 Apr 2016 00:27:59 +0300 Subject: [PATCH 02/16] code improvements, add examples --- Tablet/TableDirector.swift | 7 +- Tablet/TableSectionBuilder.swift | 21 +-- .../Controllers/HeaderFooterController.swift | 33 +++++ .../Controllers/MainController.swift | 31 +++++ .../ViewControllers/MainViewController.swift | 33 ----- .../Views/StoryboardTableViewCell.swift | 23 ++++ .../Resources/Storyboards/Main.storyboard | 124 +++++++++++++----- .../TabletDemo.xcodeproj/project.pbxproj | 48 ++++--- Tests/TabletTests.swift | 2 +- 9 files changed, 224 insertions(+), 98 deletions(-) create mode 100644 TabletDemo/Classes/Presentation/Controllers/HeaderFooterController.swift create mode 100644 TabletDemo/Classes/Presentation/Controllers/MainController.swift delete mode 100644 TabletDemo/Classes/Presentation/Main/ViewControllers/MainViewController.swift create mode 100644 TabletDemo/Classes/Presentation/Views/StoryboardTableViewCell.swift diff --git a/Tablet/TableDirector.swift b/Tablet/TableDirector.swift index 0e54392..59dccca 100644 --- a/Tablet/TableDirector.swift +++ b/Tablet/TableDirector.swift @@ -26,14 +26,14 @@ import Foundation */ public class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate { - public private(set) weak var tableView: UITableView! + public unowned let tableView: UITableView public weak var scrollDelegate: UIScrollViewDelegate? private var sections = [TableSectionBuilder]() public init(tableView: UITableView) { - super.init() - + self.tableView = tableView + super.init() self.tableView.delegate = self self.tableView.dataSource = self @@ -41,7 +41,6 @@ public class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate } deinit { - NSNotificationCenter.defaultCenter().removeObserver(self) } diff --git a/Tablet/TableSectionBuilder.swift b/Tablet/TableSectionBuilder.swift index 4bb0d68..90cddd7 100644 --- a/Tablet/TableSectionBuilder.swift +++ b/Tablet/TableSectionBuilder.swift @@ -29,10 +29,10 @@ public class TableSectionBuilder { weak var tableView: UITableView? private var builders = [RowBuilder]() - + public var headerTitle: String? public var footerTitle: String? - + public var headerView: UIView? public var footerView: UIView? @@ -41,18 +41,23 @@ public class TableSectionBuilder { return builders.reduce(0) { $0 + $1.numberOfRows } } - public init(headerTitle: String? = nil, footerTitle: String? = nil, rows: [RowBuilder]? = nil) { - - self.headerTitle = headerTitle - self.footerTitle = footerTitle - + public init(rows: [RowBuilder]? = nil) { + if let initialRows = rows { builders.appendContentsOf(initialRows) } } - public init(headerView: UIView? = nil, footerView: UIView? = nil) { + public convenience init(headerTitle: String?, footerTitle: String?, rows: [RowBuilder]?) { + self.init(rows: rows) + + self.headerTitle = headerTitle + self.footerTitle = footerTitle + } + public convenience init(headerView: UIView?, footerView: UIView?, rows: [RowBuilder]?) { + self.init(rows: rows) + self.headerView = headerView self.footerView = footerView } diff --git a/TabletDemo/Classes/Presentation/Controllers/HeaderFooterController.swift b/TabletDemo/Classes/Presentation/Controllers/HeaderFooterController.swift new file mode 100644 index 0000000..9666cca --- /dev/null +++ b/TabletDemo/Classes/Presentation/Controllers/HeaderFooterController.swift @@ -0,0 +1,33 @@ +// +// HeaderFooterController.swift +// TabletDemo +// +// Created by Max Sokolov on 16/04/16. +// Copyright © 2016 Tablet. All rights reserved. +// + +import UIKit +import Tablet + +class HeaderFooterController: UIViewController { + + @IBOutlet weak var tableView: UITableView! { + didSet { + tableDirector = TableDirector(tableView: tableView) + } + } + var tableDirector: TableDirector! + + override func viewDidLoad() { + super.viewDidLoad() + + let rows = TableConfigurableRowBuilder(items: ["3", "4", "5"]) + + let headerView = UIView(frame: CGRectMake(0, 0, 100, 100)) + headerView.backgroundColor = UIColor.lightGrayColor() + + let section = TableSectionBuilder(headerView: headerView, footerView: nil, rows: [rows]) + + tableDirector += section + } +} \ No newline at end of file diff --git a/TabletDemo/Classes/Presentation/Controllers/MainController.swift b/TabletDemo/Classes/Presentation/Controllers/MainController.swift new file mode 100644 index 0000000..f5213fe --- /dev/null +++ b/TabletDemo/Classes/Presentation/Controllers/MainController.swift @@ -0,0 +1,31 @@ +// +// MainController.swift +// TabletDemo +// +// Created by Max Sokolov on 16/04/16. +// Copyright © 2016 Tablet. All rights reserved. +// + +import UIKit +import Tablet + +class MainController: UIViewController { + + @IBOutlet weak var tableView: UITableView! { + didSet { + tableDirector = TableDirector(tableView: tableView) + } + } + var tableDirector: TableDirector! + + override func viewDidLoad() { + super.viewDidLoad() + + let rows = TableConfigurableRowBuilder(items: ["1", "2", "3"]) + .action(.click) { [unowned self] data -> Void in + self.performSegueWithIdentifier("headerfooter", sender: nil) + } + + tableDirector += rows + } +} \ No newline at end of file diff --git a/TabletDemo/Classes/Presentation/Main/ViewControllers/MainViewController.swift b/TabletDemo/Classes/Presentation/Main/ViewControllers/MainViewController.swift deleted file mode 100644 index 3bb415a..0000000 --- a/TabletDemo/Classes/Presentation/Main/ViewControllers/MainViewController.swift +++ /dev/null @@ -1,33 +0,0 @@ -// -// MainViewController.swift -// TabletDemo -// -// Created by Max Sokolov on 19/03/16. -// Copyright © 2016 Tablet. All rights reserved. -// - -import Foundation -import UIKit -import Tablet - -class MainViewController : UITableViewController { - - var tableDirector: TableDirector! - - override func viewDidLoad() { - super.viewDidLoad() - - tableDirector = TableDirector(tableView: tableView) - - tableDirector += TableRowBuilder(items: [1, 2, 3, 4], id: "cell") - .action(.configure) { data -> Void in - - data.cell?.accessoryType = .DisclosureIndicator - data.cell?.textLabel?.text = "\(data.item)" - } - .action(.click) { data -> Void in - - - } - } -} \ No newline at end of file diff --git a/TabletDemo/Classes/Presentation/Views/StoryboardTableViewCell.swift b/TabletDemo/Classes/Presentation/Views/StoryboardTableViewCell.swift new file mode 100644 index 0000000..2e4884b --- /dev/null +++ b/TabletDemo/Classes/Presentation/Views/StoryboardTableViewCell.swift @@ -0,0 +1,23 @@ +// +// StoryboardTableViewCell.swift +// TabletDemo +// +// Created by Max Sokolov on 16/04/16. +// Copyright © 2016 Tablet. All rights reserved. +// + +import UIKit +import Tablet + +class StoryboardTableViewCell: UITableViewCell, ConfigurableCell { + + typealias T = String + + func configure(value: T) { + textLabel?.text = value + } + + static func estimatedHeight() -> Float { + return 44 + } +} \ No newline at end of file diff --git a/TabletDemo/Resources/Storyboards/Main.storyboard b/TabletDemo/Resources/Storyboards/Main.storyboard index 2cf7895..1a1d1c2 100644 --- a/TabletDemo/Resources/Storyboards/Main.storyboard +++ b/TabletDemo/Resources/Storyboards/Main.storyboard @@ -1,39 +1,10 @@ - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -45,12 +16,101 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TabletDemo/TabletDemo.xcodeproj/project.pbxproj b/TabletDemo/TabletDemo.xcodeproj/project.pbxproj index 4d330c4..9779299 100644 --- a/TabletDemo/TabletDemo.xcodeproj/project.pbxproj +++ b/TabletDemo/TabletDemo.xcodeproj/project.pbxproj @@ -10,8 +10,10 @@ DAC2D5CA1C9D303E009E9C19 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAC2D5C91C9D303E009E9C19 /* AppDelegate.swift */; }; DAC2D5CF1C9D30A7009E9C19 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DAC2D5CD1C9D30A7009E9C19 /* Main.storyboard */; }; DAC2D5D01C9D30A7009E9C19 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DAC2D5CE1C9D30A7009E9C19 /* LaunchScreen.storyboard */; }; - DAC2D5D41C9D3118009E9C19 /* MainViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAC2D5D31C9D3118009E9C19 /* MainViewController.swift */; }; DAC2D69C1C9E75E3009E9C19 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DAC2D69B1C9E75E3009E9C19 /* Assets.xcassets */; }; + DACB71761CC2D63D00432BD3 /* MainController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DACB71751CC2D63D00432BD3 /* MainController.swift */; }; + DACB71781CC2D6ED00432BD3 /* StoryboardTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DACB71771CC2D6ED00432BD3 /* StoryboardTableViewCell.swift */; }; + DACB717A1CC2D89D00432BD3 /* HeaderFooterController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DACB71791CC2D89D00432BD3 /* HeaderFooterController.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -19,9 +21,11 @@ DAC2D5C91C9D303E009E9C19 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; DAC2D5CD1C9D30A7009E9C19 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = ""; }; DAC2D5CE1C9D30A7009E9C19 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; }; - DAC2D5D31C9D3118009E9C19 /* MainViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainViewController.swift; sourceTree = ""; }; DAC2D69B1C9E75E3009E9C19 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; DAC2D69D1C9E78B5009E9C19 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + DACB71751CC2D63D00432BD3 /* MainController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainController.swift; sourceTree = ""; }; + DACB71771CC2D6ED00432BD3 /* StoryboardTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StoryboardTableViewCell.swift; sourceTree = ""; }; + DACB71791CC2D89D00432BD3 /* HeaderFooterController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HeaderFooterController.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -64,7 +68,8 @@ DAC2D5C71C9D3005009E9C19 /* Presentation */ = { isa = PBXGroup; children = ( - DAC2D5D11C9D30D8009E9C19 /* Main */, + DACB71731CC2D5ED00432BD3 /* Controllers */, + DACB71741CC2D5FD00432BD3 /* Views */, ); path = Presentation; sourceTree = ""; @@ -96,22 +101,6 @@ path = Storyboards; sourceTree = ""; }; - DAC2D5D11C9D30D8009E9C19 /* Main */ = { - isa = PBXGroup; - children = ( - DAC2D5D21C9D30E4009E9C19 /* ViewControllers */, - ); - path = Main; - sourceTree = ""; - }; - DAC2D5D21C9D30E4009E9C19 /* ViewControllers */ = { - isa = PBXGroup; - children = ( - DAC2D5D31C9D3118009E9C19 /* MainViewController.swift */, - ); - path = ViewControllers; - sourceTree = ""; - }; DAC2D69A1C9E75BE009E9C19 /* Assets */ = { isa = PBXGroup; children = ( @@ -120,6 +109,23 @@ path = Assets; sourceTree = ""; }; + DACB71731CC2D5ED00432BD3 /* Controllers */ = { + isa = PBXGroup; + children = ( + DACB71751CC2D63D00432BD3 /* MainController.swift */, + DACB71791CC2D89D00432BD3 /* HeaderFooterController.swift */, + ); + path = Controllers; + sourceTree = ""; + }; + DACB71741CC2D5FD00432BD3 /* Views */ = { + isa = PBXGroup; + children = ( + DACB71771CC2D6ED00432BD3 /* StoryboardTableViewCell.swift */, + ); + path = Views; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -192,8 +198,10 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DAC2D5D41C9D3118009E9C19 /* MainViewController.swift in Sources */, + DACB71781CC2D6ED00432BD3 /* StoryboardTableViewCell.swift in Sources */, + DACB71761CC2D63D00432BD3 /* MainController.swift in Sources */, DAC2D5CA1C9D303E009E9C19 /* AppDelegate.swift in Sources */, + DACB717A1CC2D89D00432BD3 /* HeaderFooterController.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Tests/TabletTests.swift b/Tests/TabletTests.swift index 0cbe395..b8d3e07 100644 --- a/Tests/TabletTests.swift +++ b/Tests/TabletTests.swift @@ -157,7 +157,7 @@ class TabletTests: XCTestCase { let sectionHeaderView = UIView() let sectionFooterView = UIView() - let section = TableSectionBuilder(headerView: sectionHeaderView, footerView: sectionFooterView) + let section = TableSectionBuilder(headerView: sectionHeaderView, footerView: sectionFooterView, rows: nil) section += row testController.view.hidden = false From 03186a2cf54580c8d1a8771f752b312aabbf5304 Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Sat, 30 Apr 2016 00:14:07 +0300 Subject: [PATCH 03/16] generic improvements --- Tablet/TableRowBuilder.swift | 94 +++++++++---------- Tablet/Tablet.swift | 10 +- .../Controllers/MainController.swift | 2 + 3 files changed, 52 insertions(+), 54 deletions(-) diff --git a/Tablet/TableRowBuilder.swift b/Tablet/TableRowBuilder.swift index e5a438d..6ed6869 100644 --- a/Tablet/TableRowBuilder.swift +++ b/Tablet/TableRowBuilder.swift @@ -67,23 +67,23 @@ public class RowBuilder : NSObject { /** Responsible for building cells of given type and passing items to them. */ -public class TableRowBuilder : RowBuilder { +public class TableRowBuilder : RowBuilder { - private var actions = Dictionary>() - private var items = [I]() + private var actions = Dictionary>() + private var items = [DataType]() public override var numberOfRows: Int { return items.count } - public init(item: I, id: String? = nil) { - super.init(id: id ?? NSStringFromClass(C).componentsSeparatedByString(".").last ?? "") + public init(item: DataType, id: String? = nil) { + super.init(id: id ?? String(CellType)) items.append(item) } - public init(items: [I]? = nil, id: String? = nil) { - super.init(id: id ?? NSStringFromClass(C).componentsSeparatedByString(".").last ?? "") + public init(items: [DataType]? = nil, id: String? = nil) { + super.init(id: id ?? String(CellType)) if items != nil { self.items.appendContentsOf(items!) @@ -92,19 +92,19 @@ public class TableRowBuilder : RowBuilder { // MARK: Chaining actions - public func action(key: String, closure: (data: ActionData) -> Void) -> Self { + public func action(key: String, closure: (data: ActionData) -> Void) -> Self { actions[key] = .actionBlock(closure) return self } - public func action(actionType: ActionType, closure: (data: ActionData) -> Void) -> Self { + public func action(actionType: ActionType, closure: (data: ActionData) -> Void) -> Self { actions[actionType.key] = .actionBlock(closure) return self } - public func action(actionType: ActionType, closure: (data: ActionData) -> ReturnValue) -> Self { + public func action(actionType: ActionType, closure: (data: ActionData) -> ReturnValue) -> Self { actions[actionType.key] = .actionReturnBlock(closure) return self @@ -115,7 +115,7 @@ public class TableRowBuilder : RowBuilder { override func invokeAction(actionType: ActionType, cell: UITableViewCell?, indexPath: NSIndexPath, itemIndex: Int, userInfo: [NSObject: AnyObject]?) -> AnyObject? { if let action = actions[actionType.key] { - return action.invoke(ActionData(cell: cell as? C, indexPath: indexPath, item: items[itemIndex], itemIndex: itemIndex, userInfo: userInfo)) + return action.invoke(ActionData(cell: cell as? CellType, indexPath: indexPath, item: items[itemIndex], itemIndex: itemIndex, userInfo: userInfo)) } return nil } @@ -126,9 +126,8 @@ public class TableRowBuilder : RowBuilder { return } - guard let resource = NSStringFromClass(C).componentsSeparatedByString(".").last else { return } - - let bundle = NSBundle(forClass: C.self) + let resource = String(CellType) + let bundle = NSBundle(forClass: CellType.self) if let _ = bundle.pathForResource(resource, ofType: "nib") { // existing cell @@ -136,44 +135,13 @@ public class TableRowBuilder : RowBuilder { } else { - tableView.registerClass(C.self, forCellReuseIdentifier: reusableIdentifier) + tableView.registerClass(CellType.self, forCellReuseIdentifier: reusableIdentifier) } } -} - -/** - Responsible for building configurable cells of given type and passing items to them. - */ -public class TableConfigurableRowBuilder : TableRowBuilder { - - public override var estimatedRowHeight: Float { - return C.estimatedHeight() - } - - public init(item: I) { - super.init(item: item, id: C.reusableIdentifier()) - } - - public init(items: [I]? = nil) { - super.init(items: items, id: C.reusableIdentifier()) - } - - override func invokeAction(actionType: ActionType, cell: UITableViewCell?, indexPath: NSIndexPath, itemIndex: Int, userInfo: [NSObject: AnyObject]?) -> AnyObject? { - - switch actionType { - case .configure: - (cell as? C)?.configure(items[itemIndex]) - default: break - } - return super.invokeAction(actionType, cell: cell, indexPath: indexPath, itemIndex: itemIndex, userInfo: userInfo) - } -} - -public extension TableRowBuilder { // MARK: Items manipulation - public func append(items items: [I]) { + public func append(items items: [DataType]) { self.items.appendContentsOf(items) } @@ -182,10 +150,38 @@ public extension TableRowBuilder { } } -public func +=(left: TableRowBuilder, right: I) { +/** + Responsible for building configurable cells of given type and passing items to them. + */ +public class TableConfigurableRowBuilder : TableRowBuilder { + + public override var estimatedRowHeight: Float { + return CellType.estimatedHeight() + } + + public init(item: DataType) { + super.init(item: item, id: CellType.reusableIdentifier()) + } + + public init(items: [DataType]? = nil) { + super.init(items: items, id: CellType.reusableIdentifier()) + } + + override func invokeAction(actionType: ActionType, cell: UITableViewCell?, indexPath: NSIndexPath, itemIndex: Int, userInfo: [NSObject: AnyObject]?) -> AnyObject? { + + switch actionType { + case .configure: + (cell as? CellType)?.configure(items[itemIndex]) + default: break + } + return super.invokeAction(actionType, cell: cell, indexPath: indexPath, itemIndex: itemIndex, userInfo: userInfo) + } +} + +public func +=(left: TableRowBuilder, right: DataType) { left.append(items: [right]) } -public func +=(left: TableRowBuilder, right: [I]) { +public func +=(left: TableRowBuilder, right: [DataType]) { left.append(items: right) } \ No newline at end of file diff --git a/Tablet/Tablet.swift b/Tablet/Tablet.swift index 597baac..46b8767 100644 --- a/Tablet/Tablet.swift +++ b/Tablet/Tablet.swift @@ -51,15 +51,15 @@ public enum ActionType { } } -public class ActionData { +public class ActionData { - public let cell: C? - public let item: I + public let cell: CellType? + public let item: DataType public let itemIndex: Int public let indexPath: NSIndexPath public let userInfo: [NSObject: AnyObject]? - init(cell: C?, indexPath: NSIndexPath, item: I, itemIndex: Int, userInfo: [NSObject: AnyObject]?) { + init(cell: CellType?, indexPath: NSIndexPath, item: DataType, itemIndex: Int, userInfo: [NSObject: AnyObject]?) { self.cell = cell self.indexPath = indexPath @@ -112,6 +112,6 @@ public protocol ConfigurableCell { public extension ConfigurableCell where Self: UITableViewCell { static func reusableIdentifier() -> String { - return NSStringFromClass(self).componentsSeparatedByString(".").last ?? "" + return String(self) } } \ No newline at end of file diff --git a/TabletDemo/Classes/Presentation/Controllers/MainController.swift b/TabletDemo/Classes/Presentation/Controllers/MainController.swift index f5213fe..36f107f 100644 --- a/TabletDemo/Classes/Presentation/Controllers/MainController.swift +++ b/TabletDemo/Classes/Presentation/Controllers/MainController.swift @@ -25,6 +25,8 @@ class MainController: UIViewController { .action(.click) { [unowned self] data -> Void in self.performSegueWithIdentifier("headerfooter", sender: nil) } + + print("", String(TableDirector.self)) tableDirector += rows } From 32a257149e65f06d44ca4199de1ca46684f1c514 Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Mon, 2 May 2016 22:03:52 +0300 Subject: [PATCH 04/16] some refactoring --- Tablet/TableRowBuilder.swift | 40 ++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/Tablet/TableRowBuilder.swift b/Tablet/TableRowBuilder.swift index 6ed6869..b3429d2 100644 --- a/Tablet/TableRowBuilder.swift +++ b/Tablet/TableRowBuilder.swift @@ -23,19 +23,19 @@ import Foundation public typealias ReturnValue = AnyObject? -enum ActionHandler { - - case actionBlock((data: ActionData) -> Void) - case actionReturnBlock((data: ActionData) -> AnyObject?) - - func invoke(data: ActionData) -> ReturnValue { - +enum ActionHandler { + + case Handler((data: ActionData) -> Void) + case ReturnValueHandler((data: ActionData) -> AnyObject?) + + func invoke(data: ActionData) -> ReturnValue { + switch (self) { - case .actionBlock(let closure): - closure(data: data) + case .Handler(let handler): + handler(data: data) return true - case .actionReturnBlock(let closure): - return closure(data: data) + case .ReturnValueHandler(let handler): + return handler(data: data) } } } @@ -69,7 +69,7 @@ public class RowBuilder : NSObject { */ public class TableRowBuilder : RowBuilder { - private var actions = Dictionary>() + private var actions = [String: ActionHandler]() private var items = [DataType]() public override var numberOfRows: Int { @@ -92,29 +92,29 @@ public class TableRowBuilder // MARK: Chaining actions - public func action(key: String, closure: (data: ActionData) -> Void) -> Self { + public func action(key: String, handler: (data: ActionData) -> Void) -> Self { - actions[key] = .actionBlock(closure) + actions[key] = .Handler(handler) return self } - public func action(actionType: ActionType, closure: (data: ActionData) -> Void) -> Self { + public func action(type: ActionType, handler: (data: ActionData) -> Void) -> Self { - actions[actionType.key] = .actionBlock(closure) + actions[type.key] = .Handler(handler) return self } - public func action(actionType: ActionType, closure: (data: ActionData) -> ReturnValue) -> Self { + public func action(type: ActionType, handler: (data: ActionData) -> ReturnValue) -> Self { - actions[actionType.key] = .actionReturnBlock(closure) + actions[type.key] = .ReturnValueHandler(handler) return self } // MARK: Internal - override func invokeAction(actionType: ActionType, cell: UITableViewCell?, indexPath: NSIndexPath, itemIndex: Int, userInfo: [NSObject: AnyObject]?) -> AnyObject? { + override func invokeAction(type: ActionType, cell: UITableViewCell?, indexPath: NSIndexPath, itemIndex: Int, userInfo: [NSObject: AnyObject]?) -> AnyObject? { - if let action = actions[actionType.key] { + if let action = actions[type.key] { return action.invoke(ActionData(cell: cell as? CellType, indexPath: indexPath, item: items[itemIndex], itemIndex: itemIndex, userInfo: userInfo)) } return nil From 7083462aca4b279e28dbeac6da4d661029f7d5e1 Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Fri, 6 May 2016 19:03:36 +0300 Subject: [PATCH 05/16] add valueAction --- .../UserInterfaceState.xcuserstate | Bin 10802 -> 12275 bytes Tablet/TableRowBuilder.swift | 8 ++++---- .../Controllers/MainController.swift | 12 +++++++++++- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Tablet.xcworkspace/xcuserdata/max.xcuserdatad/UserInterfaceState.xcuserstate b/Tablet.xcworkspace/xcuserdata/max.xcuserdatad/UserInterfaceState.xcuserstate index 87b462673907f2820a85dec730732ebdebebac16..c9f97f271711b0245f54b2ae1789a32474cd1224 100644 GIT binary patch delta 7635 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 delta 6437 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 A3IG5A diff --git a/Tablet/TableRowBuilder.swift b/Tablet/TableRowBuilder.swift index b3429d2..e1ba1bc 100644 --- a/Tablet/TableRowBuilder.swift +++ b/Tablet/TableRowBuilder.swift @@ -26,7 +26,7 @@ public typealias ReturnValue = AnyObject? enum ActionHandler { case Handler((data: ActionData) -> Void) - case ReturnValueHandler((data: ActionData) -> AnyObject?) + case ValueHandler((data: ActionData) -> AnyObject?) func invoke(data: ActionData) -> ReturnValue { @@ -34,7 +34,7 @@ enum ActionHandler { case .Handler(let handler): handler(data: data) return true - case .ReturnValueHandler(let handler): + case .ValueHandler(let handler): return handler(data: data) } } @@ -104,9 +104,9 @@ public class TableRowBuilder return self } - public func action(type: ActionType, handler: (data: ActionData) -> ReturnValue) -> Self { + public func valueAction(type: ActionType, handler: (data: ActionData) -> ReturnValue) -> Self { - actions[type.key] = .ReturnValueHandler(handler) + actions[type.key] = .ValueHandler(handler) return self } diff --git a/TabletDemo/Classes/Presentation/Controllers/MainController.swift b/TabletDemo/Classes/Presentation/Controllers/MainController.swift index 36f107f..2c1ad9e 100644 --- a/TabletDemo/Classes/Presentation/Controllers/MainController.swift +++ b/TabletDemo/Classes/Presentation/Controllers/MainController.swift @@ -22,9 +22,19 @@ class MainController: UIViewController { super.viewDidLoad() let rows = TableConfigurableRowBuilder(items: ["1", "2", "3"]) - .action(.click) { [unowned self] data -> Void in + .action(.click) { [unowned self] e in self.performSegueWithIdentifier("headerfooter", sender: nil) } + .valueAction(.click) { data in + return 10 + } + .action(.click) { data in + self.performSegueWithIdentifier("headerfooter", sender: nil) + } + .action(.click) { data in + + + } print("", String(TableDirector.self)) From c3fda15cb4c289326ef3af871f24647e1cbfece3 Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Sat, 7 May 2016 23:28:15 +0300 Subject: [PATCH 06/16] method names refactoring --- Tablet/TableDirector.swift | 20 +++++++++---------- Tablet/TableRowBuilder.swift | 20 +++++++++---------- .../Controllers/HeaderFooterController.swift | 2 +- .../Controllers/MainController.swift | 4 +--- 4 files changed, 22 insertions(+), 24 deletions(-) diff --git a/Tablet/TableDirector.swift b/Tablet/TableDirector.swift index 59dccca..7d51a48 100644 --- a/Tablet/TableDirector.swift +++ b/Tablet/TableDirector.swift @@ -60,10 +60,10 @@ public class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate // MARK: Public - public func invokeAction(action: ActionType, cell: UITableViewCell?, indexPath: NSIndexPath) -> AnyObject? { + public func invoke(action action: ActionType, cell: UITableViewCell?, indexPath: NSIndexPath) -> AnyObject? { let builder = builderAtIndexPath(indexPath) - return builder.0.invokeAction(action, cell: cell, indexPath: indexPath, itemIndex: builder.1, userInfo: nil) + return builder.0.invoke(action: action, cell: cell, indexPath: indexPath, itemIndex: builder.1, userInfo: nil) } public override func respondsToSelector(selector: Selector) -> Bool { @@ -81,7 +81,7 @@ public class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate if let action = notification.object as? Action, indexPath = tableView.indexPathForCell(action.cell) { let builder = builderAtIndexPath(indexPath) - builder.0.invokeAction(.custom(action.key), cell: action.cell, indexPath: indexPath, itemIndex: builder.1, userInfo: notification.userInfo) + builder.0.invoke(action: .custom(action.key), cell: action.cell, indexPath: indexPath, itemIndex: builder.1, userInfo: notification.userInfo) } } } @@ -109,7 +109,7 @@ public extension TableDirector { cell.layoutIfNeeded() } - builder.0.invokeAction(.configure, cell: cell, indexPath: indexPath, itemIndex: builder.1, userInfo: nil) + builder.0.invoke(action: .configure, cell: cell, indexPath: indexPath, itemIndex: builder.1, userInfo: nil) return cell } @@ -155,7 +155,7 @@ public extension TableDirector { } func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { - return invokeAction(.height, cell: nil, indexPath: indexPath) as? CGFloat ?? UITableViewAutomaticDimension + return invoke(action: .height, cell: nil, indexPath: indexPath) as? CGFloat ?? UITableViewAutomaticDimension } /*func tableView(tableView: UITableView, willSelectRowAtIndexPath indexPath: NSIndexPath) -> NSIndexPath? { @@ -167,23 +167,23 @@ public extension TableDirector { let cell = tableView.cellForRowAtIndexPath(indexPath) - if invokeAction(.click, cell: cell, indexPath: indexPath) != nil { + if invoke(action: .click, cell: cell, indexPath: indexPath) != nil { tableView.deselectRowAtIndexPath(indexPath, animated: true) } else { - invokeAction(.select, cell: cell, indexPath: indexPath) + invoke(action: .select, cell: cell, indexPath: indexPath) } } func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) { - invokeAction(.deselect, cell: tableView.cellForRowAtIndexPath(indexPath), indexPath: indexPath) + invoke(action: .deselect, cell: tableView.cellForRowAtIndexPath(indexPath), indexPath: indexPath) } func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { - invokeAction(.willDisplay, cell: cell, indexPath: indexPath) + invoke(action: .willDisplay, cell: cell, indexPath: indexPath) } func tableView(tableView: UITableView, shouldHighlightRowAtIndexPath indexPath: NSIndexPath) -> Bool { - return invokeAction(.shouldHighlight, cell: tableView.cellForRowAtIndexPath(indexPath), indexPath: indexPath) as? Bool ?? true + return invoke(action: .shouldHighlight, cell: tableView.cellForRowAtIndexPath(indexPath), indexPath: indexPath) as? Bool ?? true } } diff --git a/Tablet/TableRowBuilder.swift b/Tablet/TableRowBuilder.swift index e1ba1bc..9be3369 100644 --- a/Tablet/TableRowBuilder.swift +++ b/Tablet/TableRowBuilder.swift @@ -56,7 +56,7 @@ public class RowBuilder : NSObject { // MARK: internal methods, must be overriden in subclass - func invokeAction(actionType: ActionType, cell: UITableViewCell?, indexPath: NSIndexPath, itemIndex: Int, userInfo: [NSObject: AnyObject]?) -> AnyObject? { + func invoke(action action: ActionType, cell: UITableViewCell?, indexPath: NSIndexPath, itemIndex: Int, userInfo: [NSObject: AnyObject]?) -> AnyObject? { return nil } @@ -67,7 +67,7 @@ public class RowBuilder : NSObject { /** Responsible for building cells of given type and passing items to them. */ -public class TableRowBuilder : RowBuilder { +public class TableBaseRowBuilder : RowBuilder { private var actions = [String: ActionHandler]() private var items = [DataType]() @@ -112,9 +112,9 @@ public class TableRowBuilder // MARK: Internal - override func invokeAction(type: ActionType, cell: UITableViewCell?, indexPath: NSIndexPath, itemIndex: Int, userInfo: [NSObject: AnyObject]?) -> AnyObject? { + override func invoke(action action: ActionType, cell: UITableViewCell?, indexPath: NSIndexPath, itemIndex: Int, userInfo: [NSObject: AnyObject]?) -> AnyObject? { - if let action = actions[type.key] { + if let action = actions[action.key] { return action.invoke(ActionData(cell: cell as? CellType, indexPath: indexPath, item: items[itemIndex], itemIndex: itemIndex, userInfo: userInfo)) } return nil @@ -153,7 +153,7 @@ public class TableRowBuilder /** Responsible for building configurable cells of given type and passing items to them. */ -public class TableConfigurableRowBuilder : TableRowBuilder { +public class TableRowBuilder : TableBaseRowBuilder { public override var estimatedRowHeight: Float { return CellType.estimatedHeight() @@ -167,21 +167,21 @@ public class TableConfigurableRowBuilder AnyObject? { + override func invoke(action action: ActionType, cell: UITableViewCell?, indexPath: NSIndexPath, itemIndex: Int, userInfo: [NSObject: AnyObject]?) -> AnyObject? { - switch actionType { + switch action { case .configure: (cell as? CellType)?.configure(items[itemIndex]) default: break } - return super.invokeAction(actionType, cell: cell, indexPath: indexPath, itemIndex: itemIndex, userInfo: userInfo) + return super.invoke(action: action, cell: cell, indexPath: indexPath, itemIndex: itemIndex, userInfo: userInfo) } } -public func +=(left: TableRowBuilder, right: DataType) { +public func +=(left: TableBaseRowBuilder, right: DataType) { left.append(items: [right]) } -public func +=(left: TableRowBuilder, right: [DataType]) { +public func +=(left: TableBaseRowBuilder, right: [DataType]) { left.append(items: right) } \ No newline at end of file diff --git a/TabletDemo/Classes/Presentation/Controllers/HeaderFooterController.swift b/TabletDemo/Classes/Presentation/Controllers/HeaderFooterController.swift index 9666cca..1e1a7c7 100644 --- a/TabletDemo/Classes/Presentation/Controllers/HeaderFooterController.swift +++ b/TabletDemo/Classes/Presentation/Controllers/HeaderFooterController.swift @@ -21,7 +21,7 @@ class HeaderFooterController: UIViewController { override func viewDidLoad() { super.viewDidLoad() - let rows = TableConfigurableRowBuilder(items: ["3", "4", "5"]) + let rows = TableRowBuilder(items: ["3", "4", "5"]) let headerView = UIView(frame: CGRectMake(0, 0, 100, 100)) headerView.backgroundColor = UIColor.lightGrayColor() diff --git a/TabletDemo/Classes/Presentation/Controllers/MainController.swift b/TabletDemo/Classes/Presentation/Controllers/MainController.swift index 2c1ad9e..11e982b 100644 --- a/TabletDemo/Classes/Presentation/Controllers/MainController.swift +++ b/TabletDemo/Classes/Presentation/Controllers/MainController.swift @@ -21,7 +21,7 @@ class MainController: UIViewController { override func viewDidLoad() { super.viewDidLoad() - let rows = TableConfigurableRowBuilder(items: ["1", "2", "3"]) + let rows = TableRowBuilder(items: ["1", "2", "3"]) .action(.click) { [unowned self] e in self.performSegueWithIdentifier("headerfooter", sender: nil) } @@ -35,8 +35,6 @@ class MainController: UIViewController { } - - print("", String(TableDirector.self)) tableDirector += rows } From 87e7dbd6c43dceb6e790d808272753784ffc7ccd Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Sun, 8 May 2016 00:39:58 +0300 Subject: [PATCH 07/16] move back to RowBuilder protocol --- Tablet/TableDirector.swift | 74 ++++++++----------- Tablet/TableRowBuilder.swift | 70 ++++++++---------- Tablet/TableSectionBuilder.swift | 8 +- .../Controllers/MainController.swift | 10 --- 4 files changed, 64 insertions(+), 98 deletions(-) diff --git a/Tablet/TableDirector.swift b/Tablet/TableDirector.swift index 7d51a48..a44748e 100644 --- a/Tablet/TableDirector.swift +++ b/Tablet/TableDirector.swift @@ -74,7 +74,7 @@ public class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate return scrollDelegate?.respondsToSelector(selector) == true ? scrollDelegate : super.forwardingTargetForSelector(selector) } - // MARK: Internal + // MARK: - Internal - func didReceiveAction(notification: NSNotification) { @@ -84,26 +84,23 @@ public class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate builder.0.invoke(action: .custom(action.key), cell: action.cell, indexPath: indexPath, itemIndex: builder.1, userInfo: notification.userInfo) } } -} - -public extension TableDirector { - + // MARK: UITableViewDataSource - configuration - func numberOfSectionsInTableView(tableView: UITableView) -> Int { + public func numberOfSectionsInTableView(tableView: UITableView) -> Int { return sections.count } - func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + public func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return sections[section].numberOfRowsInSection } - func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { + public func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let builder = builderAtIndexPath(indexPath) let cell = tableView.dequeueReusableCellWithIdentifier(builder.0.reusableIdentifier, forIndexPath: indexPath) - + if cell.frame.size.width != tableView.frame.size.width { cell.frame = CGRectMake(0, 0, tableView.frame.size.width, cell.frame.size.height) cell.layoutIfNeeded() @@ -113,58 +110,47 @@ public extension TableDirector { return cell } -} - -public extension TableDirector { - + // MARK: UITableViewDataSource - section setup - func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? { + public func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? { return sections[section].headerTitle } - func tableView(tableView: UITableView, titleForFooterInSection section: Int) -> String? { + public func tableView(tableView: UITableView, titleForFooterInSection section: Int) -> String? { return sections[section].footerTitle } // MARK: UITableViewDelegate - section setup - func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { + public func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { return sections[section].headerView } - func tableView(tableView: UITableView, viewForFooterInSection section: Int) -> UIView? { + public func tableView(tableView: UITableView, viewForFooterInSection section: Int) -> UIView? { return sections[section].footerView } - func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { + public func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { return sections[section].headerView?.frame.size.height ?? UITableViewAutomaticDimension } - - func tableView(tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat { + + public func tableView(tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat { return sections[section].footerView?.frame.size.height ?? UITableViewAutomaticDimension } -} - -public extension TableDirector { - + // MARK: UITableViewDelegate - actions - - func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { + + public func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { return CGFloat(builderAtIndexPath(indexPath).0.estimatedRowHeight) } - func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { + public func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { return invoke(action: .height, cell: nil, indexPath: indexPath) as? CGFloat ?? UITableViewAutomaticDimension } - /*func tableView(tableView: UITableView, willSelectRowAtIndexPath indexPath: NSIndexPath) -> NSIndexPath? { + public func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { - return invokeAction(.willSelect, cell: tableView.cellForRowAtIndexPath(indexPath), indexPath: indexPath) as? NSIndexPath - }*/ - - func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { - let cell = tableView.cellForRowAtIndexPath(indexPath) if invoke(action: .click, cell: cell, indexPath: indexPath) != nil { @@ -174,29 +160,31 @@ public extension TableDirector { } } - func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) { + public func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) { invoke(action: .deselect, cell: tableView.cellForRowAtIndexPath(indexPath), indexPath: indexPath) } - func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { + public func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { invoke(action: .willDisplay, cell: cell, indexPath: indexPath) } - func tableView(tableView: UITableView, shouldHighlightRowAtIndexPath indexPath: NSIndexPath) -> Bool { + public func tableView(tableView: UITableView, shouldHighlightRowAtIndexPath indexPath: NSIndexPath) -> Bool { return invoke(action: .shouldHighlight, cell: tableView.cellForRowAtIndexPath(indexPath), indexPath: indexPath) as? Bool ?? true } -} - -public extension TableDirector { - - // MARK: Sections manipulation - + + /*func tableView(tableView: UITableView, willSelectRowAtIndexPath indexPath: NSIndexPath) -> NSIndexPath? { + + return invokeAction(.willSelect, cell: tableView.cellForRowAtIndexPath(indexPath), indexPath: indexPath) as? NSIndexPath + }*/ + + // MARK: - Sections manipulation - + public func append(section section: TableSectionBuilder) { append(sections: [section]) } public func append(sections sections: [TableSectionBuilder]) { - + sections.forEach { $0.willMoveToDirector(tableView) } self.sections.appendContentsOf(sections) } diff --git a/Tablet/TableRowBuilder.swift b/Tablet/TableRowBuilder.swift index 9be3369..a49121a 100644 --- a/Tablet/TableRowBuilder.swift +++ b/Tablet/TableRowBuilder.swift @@ -40,28 +40,14 @@ enum ActionHandler { } } -public class RowBuilder : NSObject { +public protocol RowBuilder { - public private(set) var reusableIdentifier: String - public var numberOfRows: Int { - return 0 - } - public var estimatedRowHeight: Float { - return 44 - } + var reusableIdentifier: String { get } + var numberOfRows: Int { get } + var estimatedRowHeight: Float { get } - init(id: String) { - reusableIdentifier = id - } - - // MARK: internal methods, must be overriden in subclass - - func invoke(action action: ActionType, cell: UITableViewCell?, indexPath: NSIndexPath, itemIndex: Int, userInfo: [NSObject: AnyObject]?) -> AnyObject? { - return nil - } - - func registerCell(inTableView tableView: UITableView) { - } + func invoke(action action: ActionType, cell: UITableViewCell?, indexPath: NSIndexPath, itemIndex: Int, userInfo: [NSObject: AnyObject]?) -> AnyObject? + func registerCell(inTableView tableView: UITableView) } /** @@ -72,25 +58,32 @@ public class TableBaseRowBuilder]() private var items = [DataType]() - public override var numberOfRows: Int { + public let reusableIdentifier: String + + public var numberOfRows: Int { return items.count } + public var estimatedRowHeight: Float { + return 44 + } + public init(item: DataType, id: String? = nil) { - super.init(id: id ?? String(CellType)) - + + reusableIdentifier = id ?? String(CellType) items.append(item) } public init(items: [DataType]? = nil, id: String? = nil) { - super.init(id: id ?? String(CellType)) - - if items != nil { - self.items.appendContentsOf(items!) + + reusableIdentifier = id ?? String(CellType) + + if let items = items { + self.items.appendContentsOf(items) } } - // MARK: Chaining actions + // MARK: - Chaining actions - public func action(key: String, handler: (data: ActionData) -> Void) -> Self { @@ -99,7 +92,7 @@ public class TableBaseRowBuilder) -> Void) -> Self { - + actions[type.key] = .Handler(handler) return self } @@ -109,10 +102,8 @@ public class TableBaseRowBuilder AnyObject? { + + public func invoke(action action: ActionType, cell: UITableViewCell?, indexPath: NSIndexPath, itemIndex: Int, userInfo: [NSObject: AnyObject]?) -> AnyObject? { if let action = actions[action.key] { return action.invoke(ActionData(cell: cell as? CellType, indexPath: indexPath, item: items[itemIndex], itemIndex: itemIndex, userInfo: userInfo)) @@ -120,7 +111,7 @@ public class TableBaseRowBuilder AnyObject? { + public override func invoke(action action: ActionType, cell: UITableViewCell?, indexPath: NSIndexPath, itemIndex: Int, userInfo: [NSObject: AnyObject]?) -> AnyObject? { switch action { case .configure: diff --git a/Tablet/TableSectionBuilder.swift b/Tablet/TableSectionBuilder.swift index 90cddd7..a011134 100644 --- a/Tablet/TableSectionBuilder.swift +++ b/Tablet/TableSectionBuilder.swift @@ -33,8 +33,8 @@ public class TableSectionBuilder { public var headerTitle: String? public var footerTitle: String? - public var headerView: UIView? - public var footerView: UIView? + public private(set) var headerView: UIView? + public private(set) var footerView: UIView? /// A total number of rows in section of each row builder. public var numberOfRowsInSection: Int { @@ -62,7 +62,7 @@ public class TableSectionBuilder { self.footerView = footerView } - // MARK: Public + // MARK: - Public - public func clear() { builders.removeAll() @@ -78,7 +78,7 @@ public class TableSectionBuilder { builders.appendContentsOf(rows) } - // MARK: Internal + // MARK: - Internal - func builderAtIndex(index: Int) -> (RowBuilder, Int)? { diff --git a/TabletDemo/Classes/Presentation/Controllers/MainController.swift b/TabletDemo/Classes/Presentation/Controllers/MainController.swift index 11e982b..1375ff0 100644 --- a/TabletDemo/Classes/Presentation/Controllers/MainController.swift +++ b/TabletDemo/Classes/Presentation/Controllers/MainController.swift @@ -25,16 +25,6 @@ class MainController: UIViewController { .action(.click) { [unowned self] e in self.performSegueWithIdentifier("headerfooter", sender: nil) } - .valueAction(.click) { data in - return 10 - } - .action(.click) { data in - self.performSegueWithIdentifier("headerfooter", sender: nil) - } - .action(.click) { data in - - - } tableDirector += rows } From e6450068a5996ffd84999ecd60d004d45ceb7e61 Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Sun, 8 May 2016 13:24:21 +0300 Subject: [PATCH 08/16] fix tests --- Tablet/TableRowBuilder.swift | 2 +- Tests/TabletTests.swift | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Tablet/TableRowBuilder.swift b/Tablet/TableRowBuilder.swift index a49121a..7f7b6c1 100644 --- a/Tablet/TableRowBuilder.swift +++ b/Tablet/TableRowBuilder.swift @@ -154,7 +154,7 @@ public class TableRowBuilder AnyObject? { switch action { diff --git a/Tests/TabletTests.swift b/Tests/TabletTests.swift index b8d3e07..839fa6f 100644 --- a/Tests/TabletTests.swift +++ b/Tests/TabletTests.swift @@ -93,7 +93,7 @@ class TabletTests: XCTestCase { let source = ["1", "2", "3"] - let rows = TableRowBuilder(items: source) + let rows = TableBaseRowBuilder(items: source) .action(.configure) { data -> Void in XCTAssertNotNil(data.cell, "Action should have a cell") @@ -121,7 +121,7 @@ class TabletTests: XCTestCase { let testData = TestData(title: "title") testController.view.hidden = false - testController.tableDirector += TableConfigurableRowBuilder(item: testData) + testController.tableDirector += TableRowBuilder(item: testData) testController.tableView.reloadData() let cell = testController.tableView.cellForRowAtIndexPath(NSIndexPath(forRow: 0, inSection: 0)) as? TestTableViewCell @@ -132,7 +132,7 @@ class TabletTests: XCTestCase { func testSectionBuilderCreatesSectionWithHeaderAndFooterTitles() { - let row = TableConfigurableRowBuilder(items: [TestData(title: "title")]) + let row = TableRowBuilder(items: [TestData(title: "title")]) let sectionHeaderTitle = "Header Title" let sectionFooterTitle = "Footer Title" @@ -152,7 +152,7 @@ class TabletTests: XCTestCase { func testSectionBuilderCreatesSectionWithHeaderAndFooterViews() { - let row = TableConfigurableRowBuilder(items: [TestData(title: "title")]) + let row = TableRowBuilder(items: [TestData(title: "title")]) let sectionHeaderView = UIView() let sectionFooterView = UIView() @@ -175,7 +175,7 @@ class TabletTests: XCTestCase { let expectation = expectationWithDescription("cell action") - let row = TableConfigurableRowBuilder(items: [TestData(title: "title")]) + let row = TableRowBuilder(items: [TestData(title: "title")]) .action(TestTableViewCellOptions.CellAction) { data -> Void in XCTAssertNotNil(data.cell, "Action data should have a cell") From 0e42c836c1492ad86a704edff73383d58239549c Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Sun, 8 May 2016 16:30:08 +0300 Subject: [PATCH 09/16] case improvement --- Tablet/TableRowBuilder.swift | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Tablet/TableRowBuilder.swift b/Tablet/TableRowBuilder.swift index 7f7b6c1..7c57528 100644 --- a/Tablet/TableRowBuilder.swift +++ b/Tablet/TableRowBuilder.swift @@ -33,7 +33,7 @@ enum ActionHandler { switch (self) { case .Handler(let handler): handler(data: data) - return true + return nil case .ValueHandler(let handler): return handler(data: data) } @@ -157,10 +157,8 @@ public class TableRowBuilder AnyObject? { - switch action { - case .configure: + if case .configure = action { (cell as? CellType)?.configure(items[itemIndex]) - default: break } return super.invoke(action: action, cell: cell, indexPath: indexPath, itemIndex: itemIndex, userInfo: userInfo) } From 6498e39daa77527c96d77788492538c0cb1cafdd Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Sun, 15 May 2016 15:09:27 +0300 Subject: [PATCH 10/16] sections now keep reference to director instead of table view --- Tablet/TableDirector.swift | 2 +- Tablet/TableSectionBuilder.swift | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Tablet/TableDirector.swift b/Tablet/TableDirector.swift index a44748e..b79f730 100644 --- a/Tablet/TableDirector.swift +++ b/Tablet/TableDirector.swift @@ -185,7 +185,7 @@ public class TableDirector: NSObject, UITableViewDataSource, UITableViewDelegate public func append(sections sections: [TableSectionBuilder]) { - sections.forEach { $0.willMoveToDirector(tableView) } + sections.forEach { $0.tableDirector = self } self.sections.appendContentsOf(sections) } diff --git a/Tablet/TableSectionBuilder.swift b/Tablet/TableSectionBuilder.swift index a011134..546ae0d 100644 --- a/Tablet/TableSectionBuilder.swift +++ b/Tablet/TableSectionBuilder.swift @@ -26,8 +26,14 @@ import Foundation Can host several row builders. */ public class TableSectionBuilder { + + weak var tableDirector: TableDirector? { + didSet { + guard let director = tableDirector else { return } + builders.forEach { $0.registerCell(inTableView: director.tableView) } + } + } - weak var tableView: UITableView? private var builders = [RowBuilder]() public var headerTitle: String? @@ -74,7 +80,7 @@ public class TableSectionBuilder { public func append(rows rows: [RowBuilder]) { - if let tableView = tableView { rows.forEach { $0.registerCell(inTableView: tableView) } } + if let tableView = tableDirector?.tableView { rows.forEach { $0.registerCell(inTableView: tableView) } } builders.appendContentsOf(rows) } @@ -92,12 +98,6 @@ public class TableSectionBuilder { return nil } - - func willMoveToDirector(tableView: UITableView) { - - self.tableView = tableView - self.builders.forEach { $0.registerCell(inTableView: tableView) } - } } public func +=(left: TableSectionBuilder, right: RowBuilder) { From 08a56c799c38cc15b054387c84965cf3c53ee1ce Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Sun, 15 May 2016 15:53:07 +0300 Subject: [PATCH 11/16] bump readme --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index f3186ea..65c4c15 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +![Alamofire: Elegant Networking in Swift](https://raw.githubusercontent.com/maxsokolov/tablet/assets/logo.png) + #Tablet

From 39d4f8ce4e1556abad33b87586a22ce7d6c5dccc Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Sun, 15 May 2016 16:10:38 +0300 Subject: [PATCH 12/16] bump readme --- README.md | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 65c4c15..809dfd2 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@ ![Alamofire: Elegant Networking in Swift](https://raw.githubusercontent.com/maxsokolov/tablet/assets/logo.png) -#Tablet +#Tablet.swift

Build Status -Swift 2 compatible +Swift 2.2 compatible Platform iOS -CocoaPods compatible +CocoaPods compatible License: MIT

@@ -17,16 +17,16 @@ Tablet is a super lightweight yet powerful generic library that handles a comple - [x] Type-safe cells based on generics - [x] The easiest way to map your models or view models to cells - [x] Correctly handles autolayout cells with multiline labels -- [x] Chainable cell actions +- [x] Chainable cell actions (select/deselect etc.) - [x] Support cells created from code, xib, or storyboard - [x] Automatic xib/classes registration - [x] No need to subclass - [x] Extensibility - [x] Tests -That's almost all you need in your controller to build a bunch of cells in a section 😘: +That's almost all you need in your controller to build a bunch of cells in a section: ```swift -TableConfigurableRowBuilder(items: ["1", "2", "3", "4", "5"]) +let builder = TableRowBuilder(items: ["1", "2", "3", "4", "5"]) ``` Tablet respects cells reusability feature and built with performace in mind. See the Usage section to learn more. @@ -59,28 +59,28 @@ $ pod install ### Very basic -You may want to setup a very basic table view, without any custom cells. In that case simply use the `TableRowBuilder`. +You may want to setup a very basic table view, without any custom cells. In that case simply use the `TableBaseRowBuilder`. ```swift import Tablet -let rowBuilder = TableRowBuilder(items: [user1, user2, user3], id: "reusable_id") - .action(.configure) { data -> Void in +let rowBuilder = TableBaseRowBuilder(items: [user1, user2, user3], id: "reusable_id") + .action(.configure) { (data) in data.cell?.textLabel?.text = data.item.username data.cell?.detailTextLabel?.text = data.item.isActive ? "Active" : "Inactive" } -let sectionBuilder = TableSectionBuilder(headerTitle: "Users", rows: [rowBuilder]) +let sectionBuilder = TableSectionBuilder(headerTitle: "Users", footerTitle: nil, rows: [rowBuilder]) director = TableDirector(tableView: tableView) -director.appendSections(sectionBuilder) +director += sectionBuilder ``` ### Type-safe configurable cells Let's say you want to put your cell configuration logic into cell itself. Say you want to pass your view model (or even model) to your cell. -You could easily do this using the `TableConfigurableRowBuilder`. Your cell should respect the `ConfigurableCell` protocol as you may see in example below: +You could easily do this using the `TableRowBuilder`. Your cell should conforms to `ConfigurableCell` protocol as you may see in example below: ```swift import Tablet @@ -104,16 +104,16 @@ class MyTableViewCell : UITableViewCell, ConfigurableCell { } } ``` -Once you've implemented the protocol, simply use the `TableConfigurableRowBuilder` to build cells: +Once you've implemented the protocol, simply use the `TableRowBuilder` to build cells: ```swift import Tablet -let rowBuilder = TableConfigurableRowBuilder() -rowBuilder.appendItems(users) +let rowBuilder = TableRowBuilder() +rowBuilder += users director = TableDirector(tableView: tableView) -tableDirector.appendSection(TableSectionBuilder(rows: [rowBuilder])) +tableDirector += TableSectionBuilder(rows: [rowBuilder]) ``` ### Cell actions @@ -124,13 +124,13 @@ Tablet provides a chaining approach to handle actions from your cells: import Tablet let rowBuilder = TableRowBuilder(items: [user1, user2, user3], id: "reusable_id") - .action(.configure) { data -> Void in + .action(.configure) { (data) in } - .action(.click) { data -> Void in + .action(.click) { (data) in } - .action(.shouldHighlight) { data -> ReturnValue in + .valueAction(.shouldHighlight) { (data) in return false } @@ -154,14 +154,14 @@ And receive this actions with your row builder: ```swift import Tablet -let rowBuilder = TableConfigurableRowBuilder(items: users, id: "reusable_id") - .action(.click) { data -> Void in +let rowBuilder = TableRowBuilder(items: users, id: "reusable_id") + .action(.click) { (data) in } - .action(.willDisplay) { data -> Void in + .action(.willDisplay) { (data) in } - .action(kMyAction) { data -> Void in + .action(kMyAction) { (data) in } ``` @@ -186,7 +186,7 @@ extension TableDirector { Catch your action with row builder: ```swift let rowBuilder = TableConfigurableRowBuilder(items: users) - .action(kTableDirectorDidEndDisplayingCell) { data -> Void in + .action(kTableDirectorDidEndDisplayingCell) { (data) -> Void in } ``` From ae2707920f1811cc6e00d2126bda577166f5b947 Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Sun, 15 May 2016 16:11:59 +0300 Subject: [PATCH 13/16] bump podspec --- Tablet.podspec | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Tablet.podspec b/Tablet.podspec index 66dd4d3..26d41b7 100644 --- a/Tablet.podspec +++ b/Tablet.podspec @@ -1,9 +1,11 @@ Pod::Spec.new do |s| s.name = 'Tablet' - s.version = '0.4.1' + s.module_name = 'Tablet' + + s.version = '0.5.0' s.homepage = 'https://github.com/maxsokolov/tablet' - s.summary = 'Powerful type-safe tool for UITableView. Swift 2.0 is required.' + s.summary = 'Powerful type-safe tool for UITableView. Swift 2.2 is required.' s.author = { 'Max Sokolov' => 'i@maxsokolov.net' } s.license = { :type => 'MIT', :file => 'LICENSE' } @@ -11,6 +13,5 @@ Pod::Spec.new do |s| s.ios.deployment_target = '8.0' s.source_files = 'Tablet/*.swift' - s.module_name = 'Tablet' s.source = { :git => 'https://github.com/maxsokolov/tablet.git', :tag => s.version } end \ No newline at end of file From a41222300f3ff0dbf73ca08f1efad0c7b23565aa Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Sun, 15 May 2016 18:08:51 +0300 Subject: [PATCH 14/16] bump readme --- README.md | 45 +++++++++++++++++++++++---------------------- Tablet.podspec | 4 ++-- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 809dfd2..c8d8ea8 100644 --- a/README.md +++ b/README.md @@ -24,11 +24,11 @@ Tablet is a super lightweight yet powerful generic library that handles a comple - [x] Extensibility - [x] Tests -That's almost all you need in your controller to build a bunch of cells in a section: +That's almost all you need to build a bunch of cells in a section: ```swift let builder = TableRowBuilder(items: ["1", "2", "3", "4", "5"]) ``` -Tablet respects cells reusability feature and built with performace in mind. See the Usage section to learn more. +Tablet relies on self-sizing table view cells, respects cells reusability feature and also built with performace in mind. You don't have to worry about anything, just create your cells, setup autolayout constraints and be happy. See the Usage section to learn more. ## Requirements @@ -57,26 +57,6 @@ $ pod install ## Usage -### Very basic - -You may want to setup a very basic table view, without any custom cells. In that case simply use the `TableBaseRowBuilder`. - -```swift -import Tablet - -let rowBuilder = TableBaseRowBuilder(items: [user1, user2, user3], id: "reusable_id") - .action(.configure) { (data) in - - data.cell?.textLabel?.text = data.item.username - data.cell?.detailTextLabel?.text = data.item.isActive ? "Active" : "Inactive" - } - -let sectionBuilder = TableSectionBuilder(headerTitle: "Users", footerTitle: nil, rows: [rowBuilder]) - -director = TableDirector(tableView: tableView) -director += sectionBuilder -``` - ### Type-safe configurable cells Let's say you want to put your cell configuration logic into cell itself. Say you want to pass your view model (or even model) to your cell. @@ -89,6 +69,7 @@ class MyTableViewCell : UITableViewCell, ConfigurableCell { typealias T = User + // this method is not required to be implemented if your cell's id equals to class name static func reusableIdentifier() -> String { return "reusable_id" } @@ -116,6 +97,26 @@ director = TableDirector(tableView: tableView) tableDirector += TableSectionBuilder(rows: [rowBuilder]) ``` +### Very basic table view + +You may want to setup a very basic table view, without any custom cells. In that case simply use the `TableBaseRowBuilder`. + +```swift +import Tablet + +let rowBuilder = TableBaseRowBuilder(items: [user1, user2, user3], id: "reusable_id") + .action(.configure) { (data) in + + data.cell?.textLabel?.text = data.item.username + data.cell?.detailTextLabel?.text = data.item.isActive ? "Active" : "Inactive" + } + +let sectionBuilder = TableSectionBuilder(headerTitle: "Users", footerTitle: nil, rows: [rowBuilder]) + +director = TableDirector(tableView: tableView) +director += sectionBuilder +``` + ### Cell actions Tablet provides a chaining approach to handle actions from your cells: diff --git a/Tablet.podspec b/Tablet.podspec index 26d41b7..c5be448 100644 --- a/Tablet.podspec +++ b/Tablet.podspec @@ -4,7 +4,7 @@ Pod::Spec.new do |s| s.version = '0.5.0' - s.homepage = 'https://github.com/maxsokolov/tablet' + s.homepage = 'https://github.com/maxsokolov/Tablet.swift' s.summary = 'Powerful type-safe tool for UITableView. Swift 2.2 is required.' s.author = { 'Max Sokolov' => 'i@maxsokolov.net' } @@ -13,5 +13,5 @@ Pod::Spec.new do |s| s.ios.deployment_target = '8.0' s.source_files = 'Tablet/*.swift' - s.source = { :git => 'https://github.com/maxsokolov/tablet.git', :tag => s.version } + s.source = { :git => 'https://github.com/maxsokolov/Tablet.swift.git', :tag => s.version } end \ No newline at end of file From cb9789ccd8dce4ba0cc5780a3c8ba6dfe2edfb47 Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Sun, 15 May 2016 18:18:04 +0300 Subject: [PATCH 15/16] bump readme --- README.md | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index c8d8ea8..53d59eb 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ That's almost all you need to build a bunch of cells in a section: ```swift let builder = TableRowBuilder(items: ["1", "2", "3", "4", "5"]) ``` -Tablet relies on self-sizing table view cells, respects cells reusability feature and also built with performace in mind. You don't have to worry about anything, just create your cells, setup autolayout constraints and be happy. See the Usage section to learn more. +Tablet relies on self-sizing table view cells, respects cells reusability feature and also built with performace in mind. You don't have to worry about anything, just create your cells, setup autolayout constraints and be happy. See the Usage section to learn more. ## Requirements @@ -141,13 +141,17 @@ let rowBuilder = TableRowBuilder(items: [user1, user2, us ```swift import Tablet +struct MyCellActions { + static let ButtonClicked = "ButtonClicked" +} + let kMyAction = "action_key" class MyTableViewCell : UITableViewCell { @IBAction func buttonClicked(sender: UIButton) { - Action(key: kMyAction, sender: self, userInfo: nil).invoke() + Action(key: MyCellActions.ButtonClicked, sender: self, userInfo: nil).invoke() } } ``` @@ -155,14 +159,14 @@ And receive this actions with your row builder: ```swift import Tablet -let rowBuilder = TableRowBuilder(items: users, id: "reusable_id") +let rowBuilder = TableRowBuilder(items: users) .action(.click) { (data) in } .action(.willDisplay) { (data) in } - .action(kMyAction) { (data) in + .action(MyCellActions.ButtonClicked) { (data) in } ``` @@ -170,24 +174,26 @@ let rowBuilder = TableRowBuilder(items: users, id: "reusa ## Extensibility If you find that Tablet is not provide an action you need, for example you need UITableViewDelegate's `didEndDisplayingCell` method and it's not out of the box, -simply provide an extension for `TableDirector` as follow: +simply provide an extension for `TableDirector`: ```swift import Tablet -let kTableDirectorDidEndDisplayingCell = "enddisplaycell" +struct MyTableActions { + static let DidEndDisplayingCell = "DidEndDisplayingCell" +} extension TableDirector { public func tableView(tableView: UITableView, didEndDisplayingCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { - invokeAction(.custom(kTableDirectorDidEndDisplayingCell), cell: cell, indexPath: indexPath) + invoke(action: .custom(MyTableActions.DidEndDisplayingCell), cell: cell, indexPath: indexPath) } } ``` Catch your action with row builder: ```swift -let rowBuilder = TableConfigurableRowBuilder(items: users) - .action(kTableDirectorDidEndDisplayingCell) { (data) -> Void in +let rowBuilder = TableRowBuilder(items: users) + .action(MyTableActions.DidEndDisplayingCell) { (data) -> Void in } ``` From 05bc9039ea068135bf0163174b87c814596f84ce Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Sun, 15 May 2016 18:21:56 +0300 Subject: [PATCH 16/16] fix readme --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 53d59eb..a1116ae 100644 --- a/README.md +++ b/README.md @@ -145,8 +145,6 @@ struct MyCellActions { static let ButtonClicked = "ButtonClicked" } -let kMyAction = "action_key" - class MyTableViewCell : UITableViewCell { @IBAction func buttonClicked(sender: UIButton) {