Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/maxsokolov/TableKit
Type-safe declarative table views.
https://github.com/maxsokolov/TableKit
autolayout generic swift uitableview uitableviewcell
Last synced: about 1 month ago
JSON representation
Type-safe declarative table views.
- Host: GitHub
- URL: https://github.com/maxsokolov/TableKit
- Owner: maxsokolov
- License: mit
- Created: 2015-11-08T12:26:18.000Z (about 9 years ago)
- Default Branch: master
- Last Pushed: 2023-04-19T09:59:15.000Z (over 1 year ago)
- Last Synced: 2024-12-01T10:23:00.706Z (about 1 month ago)
- Topics: autolayout, generic, swift, uitableview, uitableviewcell
- Language: Swift
- Homepage:
- Size: 1.19 MB
- Stars: 702
- Watchers: 15
- Forks: 74
- Open Issues: 16
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
- awesome-ios - TableKit - Type-safe declarative table views with Swift (UI / Table View / Collection View)
- awesome-ios-star - TableKit - Type-safe declarative table views with Swift (UI / Table View / Collection View)
README
# TableKit
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
import TableKitlet row1 = TableRow(item: "1")
let row2 = TableRow(item: 2)
let row3 = TableRow(item: User(name: "John Doe", rating: 5))
```
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. Your cells have to conform to `ConfigurableCell` protocol:
```swift
class StringTableViewCell: UITableViewCell, ConfigurableCell {func configure(with string: String) {
textLabel?.text = string
}
}class UserTableViewCell: UITableViewCell, ConfigurableCell {
static var estimatedHeight: CGFloat? {
return 100
}// is not required to be implemented
// by default reuse id is equal to cell's class name
static var reuseIdentifier: String {
return "my id"
}func configure(with user: User) {
textLabel?.text = user.name
detailTextLabel?.text = "Rating: \(user.rating)"
}
}
```
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) { (options) in// you could access any useful information that relates to the action
// options.cell - StringTableViewCell?
// options.item - String
// options.indexPath - IndexPath
// options.userInfo - [AnyHashable: Any]?
}let row = TableRow(item: "some", actions: [action])
```
Or, using nice chaining approach:
```swift
let row = TableRow(item: "some")
.on(.click) { (options) in
}
.on(.shouldHighlight) { (options) -> Bool in
return false
}
```
You could find all available actions [here](Sources/TableRowAction.swift).## Custom row actions
You are able to define your own actions:
```swift
struct MyActions {
static let ButtonClicked = "ButtonClicked"
}class MyTableViewCell: UITableViewCell, ConfigurableCell {
@IBAction func myButtonClicked(sender: UIButton) {
TableCellAction(key: MyActions.ButtonClicked, sender: self).invoke()
}
}
```
And handle them accordingly:
```swift
let myAction = TableRowAction(.custom(MyActions.ButtonClicked)) { (options) in}
```
## Multiple actions with same typeIt's also possible to use multiple actions with same type:
```swift
let click1 = TableRowAction(.click) { (options) in }
click1.id = "click1" // optionallet click2 = TableRowAction(.click) { (options) in }
click2.id = "click2" // optionallet 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
## 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 var estimatedHeight: CGFloat? {
return 255
}
}
```
It's enough for most cases. But you may be not happy with this. So you could use a prototype cell to calculate cells heights. To enable this feature simply use this property:
```swift
let tableDirector = TableDirector(tableView: tableView, shouldUsePrototypeCellHeightCalculation: true)
```
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 {func configure(with url: NSURL) {
loadImageAsync(url: url, imageView: imageView)
}override func layoutSubviews() {
super.layoutSubviews()
contentView.layoutIfNeeded()
multilineLabel.preferredMaxLayoutWidth = multilineLabel.bounds.size.width
}
}
```
You have to additionally set `preferredMaxLayoutWidth` for all your multiline labels.## Functional programming
It's never been so easy to deal with table views.
```swift
let users = /* some users array */let click = TableRowAction(.click) {
}
let rows = users.filter({ $0.state == .active }).map({ TableRow(item: $0.name, actions: [click]) })
tableDirector += rows
```
Done, your table is ready.
## Automatic cell registrationTableKit can register your cells in a table view automatically. In case if your reusable cell id matches cell's xib name:
```ruby
MyTableViewCell.swift
MyTableViewCell.xib```
You can also turn off this behaviour:
```swift
let tableDirector = TableDirector(tableView: tableView, shouldUseAutomaticCellRegistration: false)
```
and register your cell manually.# 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 9.0# Changelog
Keep an eye on [changes](CHANGELOG.md).
# License
TableKit is available under the MIT license. See LICENSE for details.