I want to slim down my view controllers.
I want to manage tableview without the code of UITableViewDelegate
and UITableViewDataSource
.
That is why I created Hakuba
.
( Hakuba is one of the most famous ski resorts in Japan. )
- Don't have to write the code for
UITableViewDelegate
andUITableViewDataSource
protocols - Easy to manage your sections and cells (append/reset/insert/remove/update)
- Support dynamic cell height from ios7
- Don't have to worry about cell identifier
- Handling cell selection by trailing closure
- Easy to implement header/footer view (floating callback)
- Support for creating cells from Nibs or Storyboards
- Method chaining
- Subscript
- Support loadmore closure
- Complete example
// viewController swift file
hakuba = Hakuba(tableView: tableView)
let cellmodel = YourCellModel(title: "Title", des: "description") {
println("Did select cell with title = \(title)")
}
hakuba[2].append(cellmodel) // append a new cell model in datasource
.slide(.Fade) // show the cell of your cell model in the table view
hakuba[1].remove(1...3)
.slide(.Right)
// your cell swift file
class YourCellModel : MYCellModel {
let title: String
let des: String
init(title: String, des: String, selectionHandler: MYSelectionHandler) {
self.title = title
self.des = des
super.init(YourCell.self, selectionHandler: selectionHandler)
}
}
class YourCell : MYTableViewCell {
@IBOutlet weak var titleLabel: UILabel!
override func configureCell(data: MYCellModel) {
super.configureCell(data)
if let cellmodel = data as? YourCellModel {
titleLabel.text = cellmodel.title
}
}
}
- Initilization
private var hakuba = Hakuba(tableView: tableView)
- Section handling
let section = hakuba[secIndex] // retrieve a section or create a new section if it doesn't already exist
// inserting
hakuba.insert(section, atIndex: 1)
.slide()
// removing
hakuba.remove(index)
.slide(.Left)
hakuba.removeAll()
.slide()
// handing section index by enum
enum Section : Int, MYSectionIndex {
case Top = 0
case Center
case Bottom
var intValue: Int {
return self.rawValue
}
}
let topSection = hakuba[Section.Top]
- Cell handling
// 1. appending
hakuba[0].append(cellmodel) // append a cellmodel
.slide(.Fade) // and slide with `Fade` animation
hakuba[1].append(cellmodels) // append a list of cellmodes
.slide(.Left)
// by using section
let section = hakuba[Section.Top]
section.append(cellmodel)
.slide()
// 2. inserting
section.insert(cellmodels, atIndex: 1)
.slide(.Middle)
// 3. reseting
section.reset(cellmodels) // replace current data in section by the new data
.slide()
section.reset() // or remove all data in section
.slide()
// 4. removing
section.remove(1)
.slide(.Right)
section.remove(2...5)
.slide()
section.removeLast()
.slide()
// updating cell data
let section = hakuba[Section.Top]
section[1].property = newData
section[1].slide()
section.sort().slide()
section.shuffle().slide()
section.map
section.filter
section.reduce
section.mapFilter
section.each
section.first
section.last
section[1]
section.count
- Creating cell model
// create a cell model
let cellmodel = MYCellModel(cellClass: YourCell.self, userData: celldata) {
println("Did select")
}
// create a list of cell models from api results
let items = [...] // or your data from API
let cellmodels = items.map { item -> MYCellModel in
return MYCellModel(cellClass: YourCell.self, userData: item) {
println("Did select cell")
}
}
- Register cell, header, footer
hakuba.registerCellNib(CellClassName)
hakuba.registerCellClass(CellClassName)
hakuba.registerHeaderFooterNib(HeaderOrFooterClassName)
hakuba.registerHeaderFooterClass(HeaderOrFooterClassName)
// register a list of cells by using variadic parameters
hakuba.registerCellNib(CellClass1.self, CellClass2.self, ..., CellClassN.self)
- Section header/footer
let header = MYHeaderFooterViewModel(viewClass: CustomHeaderView.self, userData: yourData) {
println("Did select header view")
}
hakuba[Section.Top].header = header
// hide header in section 1
hakuba[Section.Center].header?.enabled = false
- Loadmore
hakuba.loadmoreEnabled = true
hakuba.loadmoreHandler = {
// request api
// append new data
}
- Commit editing
hakuba.commitEditingHandler = { [weak self] style, indexPath in
self?.hakuba[indexPath.section].remove(indexPath.row)
}
- Deselect all cells
hakuba.deselectAllCells(animated: true)
- Dynamic cell height : when you want to enable dynamic cell height, you only need to set the value of estimated height to the
height
parameter and setdynamicHeightEnabled = true
let cellmodel = MYCellModel(cellClass: YourCell.self, height: 50, userData: yourCellData) {
println("Did select cell")
}
cellmodel.dynamicHeightEnabled = true
- Callback methods in the cell class
func willAppear(data: MYCellModel)
func didDisappear(data: MYCellModel)
- Installation with CocoaPods
pod 'Hakuba'
- Copying all the files into your project
- Using submodule
- iOS 7.0+
- Xcode 6.1
Hakuba is released under the MIT license. See LICENSE for details.