From d844a753602efe2e74b5295159d4ec694f10bd72 Mon Sep 17 00:00:00 2001 From: Max Sokolov Date: Sun, 15 Nov 2015 16:12:33 +0300 Subject: [PATCH] readme updated --- README.md | 84 ++++++++++-------- .../UserInterfaceState.xcuserstate | Bin 26363 -> 26276 bytes 2 files changed, 46 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index fd08b41..e047841 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,17 @@ ![Tablet](https://raw.githubusercontent.com/maxsokolov/tablet/assets/tablet.png) -Tablet is a super lightweight yet powerful generic library that handles a complexity of UITableView's datasource and delegate in a Swift environment. Tablet's goal is to provide an easiest way to create complex table views. With Tablet you don't have to write a messy code of switch or if statement when you deal with bunch of different cells in different sections. +Tablet is a super lightweight yet powerful generic library that handles a complexity of UITableView's datasource and delegate methods in a Swift environment. Tablet's goal is to provide an easiest way to create complex table views. With Tablet you don't have to write a messy code of switch or if statements when you deal with bunch of different cells in different sections. + +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"], estimatedRowHeight: 42) +``` +Tablet respects cells reusability feature and it's type-safe. See the Usage section to learn more. ## Requirements - iOS 8.0+ -- Xcode 7.0+ +- Xcode 7.1+ ## Installation @@ -30,14 +36,16 @@ $ 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`. + ```swift import Tablet let rowBuilder = TableRowBuilder(items: [user1, user2, user3], id: "reusable_id") .action(.configure) { data in - data.cell.textLabel?.text = data.item.title - data.cell.detailTextLabel?.text = data.item.isActive ? "Active" : "Inactive" + data.cell?.textLabel?.text = data.item.username + data.cell?.detailTextLabel?.text = data.item.isActive ? "Active" : "Inactive" } let sectionBuilder = TableSectionBuilder(headerTitle: "Users", rowBuilders: [rowBuilder]) @@ -46,6 +54,40 @@ let director = TableDirector(tableView: tableView) director.appendSections(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: + +```swift +import Tablet + +class MyTableViewCell : UITableViewCell, ConfigurableCell { + + typealias Item = User + + static func reusableIdentifier() -> String { + return "reusable_id" + } + + func configureWithItem(item: Item) { // item is user here + + textLabel?.text = item.username + detailTextLabel?.text = item.isActive ? "Active" : "Inactive" + } +} +``` +Once you've implemented the protocol, simply use the `TableConfigurableRowBuilder` to build cells: + +```swift +import Tablet + +let rowBuilder = TableConfigurableRowBuilder() +rowBuilder.appendItems(users) + +tableDirector.appendSection(TableSectionBuilder(rowBuilders: [rowBuilder])) +``` + ### Cell actions Tablet provides a chaining approach to handle actions from your cells: @@ -65,40 +107,6 @@ let rowBuilder = TableRowBuilder(items: [user1, user2, us } ``` -### 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. -To provide this behaviour simply follow: - -```swift -import Tablet - -class UserTableViewCell : UITableViewCell, ConfigurableCell { - - typealias Item = User - - static func reusableIdentifier() -> String { - return "reusable_id" - } - - func configureWithItem(item: Item) { // item is user here - - textLabel?.text = item.title - detailTextLabel?.text = item.isActive ? "Active" : "Inactive" - } -} -``` -Once you follow the protocol, simply use TableConfigurableRowBuilder to build cells: - -```swift -import Tablet - -let rowBuilder = TableConfigurableRowBuilder() -rowBuilder.appendItems(users) - -tableDirector.appendSection(TableSectionBuilder(rowBuilders: [rowBuilder])) -``` - ### Custom cell actions ```swift import Tablet diff --git a/TabletDemo/TabletDemo.xcodeproj/project.xcworkspace/xcuserdata/maxsokolov.xcuserdatad/UserInterfaceState.xcuserstate b/TabletDemo/TabletDemo.xcodeproj/project.xcworkspace/xcuserdata/maxsokolov.xcuserdatad/UserInterfaceState.xcuserstate index 61803cb7d4ddd5ef8ce9bdf7b59a32f84095fc17..7cb6250b7ac308caaadbbd147c4f7405e31e9db6 100644 GIT binary patch delta 10475 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 H<(&TqtJ@w1