Giter Site home page Giter Site logo

hakuba's Introduction

Hakuba

Platform Language License Issues

I want to slim down 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. )

Features

  • Don't have to write the code for UITableViewDelegate and UITableViewDataSource 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
Quick 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 into datasource
	.bump(.fade)		// show the cell of your cell model in the table view

hakuba[1]
	.remove(1...3)
	.bump(.Right)
// your cell swift file

class YourCellModel: CellModel {
	let title: String
	let des: String

	init(title: String, des: String, selectionHandler: @escaping (Cell) -> Void) {
		self.title = title
		self.des = des
		super.init(YourCell.self, selectionHandler: selectionHandler)
	}
}


class YourCell: Cell, CellType {
	typealias CellModel = YourCellModel

	@IBOutlet weak var titleLabel: UILabel!

	override func configure() {
		guard let cellmodel = cellmodel else {
			return
		}

		titleLabel.text = cellmodel.title
  	}
}

Usage

  • Initilization
private lazy var hakuba = Hakuba(tableView: tableView)   
  • Section handling
let section = Section() // create a new section

// inserting
hakuba
	.insert(section, at: 1)
	.bump()

// removing
hakuba
	.remove(at: index)
	.bump(.left)

hakuba
	.remove(section)
	.bump()

hakuba
	.removeAll()
	.bump()

// handing section index by enum
enum YourSection: Int, SectionIndexType {
	case top
	case center
	case bottom

	static let count = 3
}
	
let topSection = hakuba[YourSection.top]
  • Cell handling
// 1. appending
hakuba[0]
	.append(cellmodel)	// append a cellmodel
	.bump(.fade)		// and bump with `Fade` animation

hakuba[1]
	.append(cellmodels)	// append a list of cellmodes
	.bump(.left)					

// by using section
let section = hakuba[YourSection.top]
section
	.append(cellmodel)
	.bump()

// 2. inserting
section
	.insert(cellmodels, at: 1)
	.bump(.middle)

// 3. reseting
section
	.reset(cellmodels)	// replace current data in section by the new data
	.bump()

section
	.reset()	// or remove all data in section
	.bump()

// 4. removing
section
	.remove(at: 1)
	.bump(.right)

section
	.remove(range: 2...5)
	.bump()

section
	.removeLast()
	.bump()
// updating cell data
let section = hakuba[YourSection.top]
section[1].property = newData
section[1]
	.bump()		
section.sort().bump()
section.shuffle().bump()
section.map
section.filter
section.reduce
section.mapFilter
section.each

section.first
section.last
section[1]
section.count
  • Register cell, header, footer
hakuba
	.registerCellByNib(CellClass.self)

hakuba
	.registerCell(CellClass.self)

hakuba
	.registerHeaderFooterByNib(HeaderOrFooterClass.self)

hakuba
	.registerHeaderFooter(HeaderOrFooterClass.self)

// register a list of cells by using variadic parameters
hakuba.registerCellByNibs(CellClass1.self, CellClass2.self, ..., CellClassN.self)
  • Section header/footer
let header = HeaderFooterViewModel(view: CustomHeaderView) {
	println("Did select header view")
}
hakuba[Section.top].header = header
  • 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)
  • Callback methods in the cell class
func willAppear(data: CellModel)
func didDisappear(data: CellModel)

Installation

  • Installation with CocoaPods
pod 'Hakuba'
  • Copying all the files into your project
  • Using submodule

Requirements

  • iOS 9.0+
  • Xcode 9+
  • Swift 4

License

Hakuba is released under the MIT license. See LICENSE for details.

hakuba's People

Contributors

ikesyo avatar keeeeen avatar nghialv avatar ra1028 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hakuba's Issues

Cell's calculatedHeight is always nil

Hey. I'm using Hakuba and so far it's great, but i think i found a bug. Cell's calculatedHeight property is always nil, even after all this calculations:

private extension CellModel {
    func calculateHeight() -> CGFloat {
        if let height = calculatedHeight {
            return height
        }

        guard let cell = delegate?.getOffscreenCell(reuseIdentifier) else {
            return estimatedHeight
        }

        cell.configureCell(self)

        let width = delegate?.tableViewWidth() ?? UIScreen.mainScreen().bounds.width
        cell.bounds = CGRectMake(0, 0, width, cell.bounds.height)
        cell.setNeedsLayout()
        cell.layoutIfNeeded()

        let size = cell.contentView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)
        return size.height + 1
    }
}

I think you should set it to a value before returning from function.

MYSelectionHandler parameter can't cast UITableViewCell.

Hi, Thanks for writing this great Library.

There is that one in trouble, It would help us if you would be compatible in the future.

MYSelectionHandler parameter is MYBaseViewProtocol.
I want to use the view of cell in the handler�, but MYBaseViewProtocol can't cast UIView.
Is not possible to change the IF of MYSelectionHandler to MYBaseViewProtocol of class that inherits from UIView?

It is expected the correspondence.
Thank you.

animation bug

tvm[0].reset(data)
tvm.fire()

tvm[0].append(newdata).fire

Breaking constraints with self.tableView.separatorStyle = .None

You calculate cell height with the separator so if there isn't one, it breaks the constraints.

 func calculateHeightForConfiguredSizingCell(cell: MYTableViewCell) -> CGFloat {
        cell.bounds = CGRectMake(0, 0, tableView?.bounds.width ?? UIScreen.mainScreen().bounds.width, cell.bounds.height)
        cell.setNeedsLayout()
        cell.layoutIfNeeded()

        let size = cell.contentView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)
        return size.height + 1.0
    }

Error when deleting row

Hello, I am trying to delete a row.
But I got this crash :

Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (1) must be equal to the number of rows contained in that section before the update (1), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).

This is how I am trying to delete my row :

self.models.value.removeFirst()
self.hakuba[0].remove(0).slide(MYAnimation.Left)

more functions

methods
  • numberOfItemsInSection
  • hideRow
MYReloadType
  • None (append data without reloading)

dynamicHeightEnabled has a problem

if i delete delay(1.5) {} , dynamicHeightEnabled has a problem
code:
let longTitle1 = "Don't have to write the code for UITableViewDelegate and UITableViewDataSource protocols"
let longTitle2 = "Support dynamic cell height from ios7"
let titles = ["title 1", "title 2", "title 3", "title 4", "title 5", longTitle1, longTitle2]

    let centerCellmodels = titles.map { [weak self] title -> CellModel in
        let data = CustomCellModel(title: "Section 1: " + title) { _ in
            print("Did select cell with title = \(title)")
            self?.pushChildViewController()
        }
        data.dynamicHeightEnabled = true
        return data
    }

        centerSection
            .append(centerCellmodels)
            .bump(.Left)

Drop iOS 7 support

How about dropping iOS 7 support due to use of the default cell sizing mechanism provided by UITableView since iOS8?

HeaderFooterView height, and backgroundColor

Hello, I need to use an HeaderFooterView on a Section.

I created a model view :

class HeaderSectionTripViewModel: HeaderFooterViewModel {

    init() {
        super.init(view: HeaderSectionTrip.self)
    }
}

and then my HeaderFooterView view :

class HeaderSectionTrip: HeaderFooterView, HeaderFooterViewType {
    typealias ViewModel = HeaderFooterViewModel

    override func configure() {
    }
}

Now this how I add my section header :

self.hakuba.registerHeaderFooterByNib(HeaderSectionTrip.self)

let section = Section()
section.header = HeaderSectionTripViewModel()
self.hakuba.append(section)

But my HeaderView is transparent. And also I need to change the height.
thanks in advance for your help.

Get a cell

Hi, is it posible to get a cell from :

self.hakuba[index]...

Because I have some UIButton, inside my cell, and I would like to catch the event, in my UIViewController.

Thanks in advance. 👍

how to get HeaderFooterView

I need to catch a UIButton action event present on a HeaderFooterView.
So I have the HeaderFooterViewModel, but how to access to the view after presentation in my UIViewController ?

Thanks in advance.

dynamic height cell doesn't work

The dynamic height cell is not working with a label in the cell.
Is there any requirements ? I know there is the minimum lines set to 0

Thanks in advance.

hakuba.registerCellsByNib cannot be used

hakuba.registerCellsByNib(HomeHeaderViewCell.self,HomeTopEvaluateViewCell.self)
error: Generic parameter 'T' could not be inferred

class HomeHeaderViewCell: Cell,CellType {

typealias CellModel = HomeHeaderViewModel

override func awakeFromNib() {
    super.awakeFromNib()
    // Initialization code
}

override func configure() {

}

override func setSelected(selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)

    // Configure the view for the selected state
}

}
class HomeTopEvaluateViewCell: Cell,CellType {

typealias CellModel = HomeTopEvaluateViewModel

override func awakeFromNib() {
    super.awakeFromNib()
    // Initialization code
}

override func setSelected(selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)

    // Configure the view for the selected state
}

}

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.