GithubHelp home page GithubHelp logo

desyatov / tablekit Goto Github PK

View Code? Open in Web Editor NEW

This project forked from maxsokolov/tablekit

0.0 1.0 0.0 1.16 MB

Type-safe declarative table views. Swift 3.0 compatible.

License: MIT License

Swift 98.67% Ruby 1.33%

tablekit's Introduction

TableKit

Build Status Swift 4.0 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

  • Type-safe generic cells
  • Functional programming style friendly
  • The easiest way to map your models or view models to cells
  • Automatic cell registration*
  • Correctly handles autolayout cells with multiline labels
  • Chainable cell actions (select/deselect etc.)
  • Support cells created from code, xib, or storyboard
  • Support different cells height calculation strategies
  • Support portrait and landscape orientations
  • No need to subclass
  • Extensibility

Getting Started

An example app is included demonstrating TableKit's functionality.

Basic usage

Create your rows:

import TableKit

let row1 = TableRow<StringTableViewCell>(item: "1")
let row2 = TableRow<IntTableViewCell>(item: 2)
let row3 = TableRow<UserTableViewCell>(item: User(name: "John Doe", rating: 5))

Put rows into section:

let section = TableSection(rows: [row1, row2, row3])

And setup your table:

let tableDirector = TableDirector(tableView: tableView)
tableDirector += section

Done. Your table is ready. Your cells have to conform to ConfigurableCell protocol:

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:

let action = TableRowAction<StringTableViewCell>(.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<StringTableViewCell>(item: "some", actions: [action])

Or, using nice chaining approach:

let row = TableRow<StringTableViewCell>(item: "some")
    .on(.click) { (options) in
	
    }
    .on(.shouldHighlight) { (options) -> Bool in
        return false
    }

You could find all available actions here.

Custom row actions

You are able to define your own actions:

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:

let myAction = TableRowAction<MyTableViewCell>(.custom(MyActions.ButtonClicked)) { (options) in

}

Multiple actions with same type

It's also possible to use multiple actions with same type:

let click1 = TableRowAction<StringTableViewCell>(.click) { (options) in }
click1.id = "click1" // optional

let click2 = TableRowAction<StringTableViewCell>(.click) { (options) in }
click2.id = "click2" // optional

let row = TableRow<StringTableViewCell>(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:

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:

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:

let tableDirector = TableDirector(tableView: tableView, shouldUsePrototypeCellHeightCalculation: true)

It does all dirty work with prototypes for you behind the scene, so you don't have to worry about anything except of your cell configuration:

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.

let users = /* some users array */

let click = TableRowAction<UserTableViewCell>(.click) {

}

let rows = users.filter({ $0.state == .active }).map({ TableRow<UserTableViewCell>(item: $0.name, actions: [click]) })

tableDirector += rows

Done, your table is ready.

Automatic cell registration

TableKit can register your cells in a table view automatically. In case if your reusable cell id mathces cell's xib name:

MyTableViewCell.swift
MyTableViewCell.xib

You can also turn off this behaviour:

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:

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 eye on changes.

License

TableKit is available under the MIT license. See LICENSE for details.

tablekit's People

Contributors

alexs555 avatar astrokin avatar jesster2k10 avatar maxsokolov avatar maxsokolovavito avatar motylevm avatar mrojas avatar sc0rch avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.