#TableKit

Build Status Swift 2.2 compatible Carthage compatible CocoaPods compatible Platform iOS License: MIT

TableKit is a super lightweight yet powerful generic library that allows you to build complex table views in a declarative type-safe manner. It hides a complexity of `UITableViewDataSource` and `UITableViewDelegate` methods behind the scene, so your code will be look clean, easy to read and nice to maintain. ## Features - [x] Type-safe generic cells - [x] Functional programming style friendly - [x] The easiest way to map your models or view models to cells - [x] Automatic cell registration - [x] Correctly handles autolayout cells with multiline labels - [x] Chainable cell actions (select/deselect etc.) - [x] Support cells created from code, xib, or storyboard - [x] Support different cells height calculation strategies - [x] Support portrait and landscape orientations - [x] No need to subclass - [x] Extensibility ## Getting Started An [example app](Demo) is included demonstrating TableKit's functionality. #### Basic usage Create your rows: ```swift let row1 = TableRow(item: "1") let row2 = TableRow(item: 2) let row3 = TableRow(item: 3.0) ``` Put rows into section: ```swift let section = TableSection(rows: [row1, row2, row3]) ``` And setup your table: ```swift let tableDirector = TableDirector(tableView: tableView) tableDirector += section ``` Done. Your table is ready. You may want to look at your cell. It has to conform to `ConfigurableCell` protocol: ```swift class StringTableViewCell: UITableViewCell, ConfigurableCell { typealias T = String func configure(string: T, isPrototype: Bool) { titleLabel.text = string } static func estimatedHeight() -> CGFloat { return 44 } } ``` You could have as many rows and sections as you need. #### Row actions It nice to have some actions that related to your cells: ```swift let action = TableRowAction(.click) { (data) in // you could access any useful information that relates to the action // data.cell - StringTableViewCell? // data.item - String // data.path - NSIndexPath } let row = TableRow(item: "some", actions: [action]) ``` Or, using nice chaining approach: ```swift let row = TableRow(item: "some") .action(TableRowAction(.click) { (data) in }) .action(TableRowAction(.shouldHighlight) { (data) -> Bool in return false }) ``` You could find all available actions [here](Sources/TableRowAction.swift). ## Advanced #### Cell height calculating strategy By default TableKit relies on self-sizing cells. In that case you have to provide an estimated height for your cells: ```swift class StringTableViewCell: UITableViewCell, ConfigurableCell { // ... static func estimatedHeight() -> CGFloat { return 44 } } ``` It's enough for most cases. But you may be not happy with this. So you could use a prototype cell to calculate cell's heights. To enable this feature simply use this property: ```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: ```swift class ImageTableViewCell: UITableViewCell, ConfigurableCell { func configure(url: NSURL, isPrototype: Bool) { if !isPrototype { loadImageAsync(url: url, imageView: imageView) } } override func layoutSubviews() { super.layoutSubviews() contentView.layoutIfNeeded() multilineLabel.preferredMaxLayoutWidth = multilineLabel.bounds.size.width } } ``` First of all you have to set `preferredMaxLayoutWidth` for all your multiline labels. And check if a configuring cell is a prototype cell. If it is, you don't have to do any additional work that not actually affect cell's height. For example you don't have to load remote image for a prototype cell. #### Functional programming It's never been so easy to deal with table views. ```swift let users = /* some users array */ let rows: [Row] = users.filter({ $0.state == .active }).map({ TableRow(item: $0.username) }) tableDirector += rows ``` Done, your table is ready. It's just awesome! ## Installation #### CocoaPods To integrate TableKit into your Xcode project using CocoaPods, specify it in your `Podfile`: ```ruby pod 'TableKit' ``` #### Carthage Add the line `github "maxsokolov/tablekit"` to your `Cartfile`. #### Manual Clone the repo and drag files from `Sources` folder into your Xcode project. ## Requirements - iOS 8.0+ - Xcode 7.0+ ## License TableKit is available under the MIT license. See LICENSE for details.