Giter Club home page Giter Club logo

collor's Introduction


Collor logo

CI Status Coverage Status Version License Platform

About

Collor is a MVVM data-oriented framework for accelerating, simplifying and ensuring UICollectionView building.
Collor was created for and improved in the Voyages-sncf.com app.

Features

Here is the list of all the features:

  • Easy to use.
  • A readable collectionView model.
  • Architectured for reusing cell.
  • Protocol / Struct oriented.
  • Scalable.
  • Never use IndexPath.
  • Never register a cell.
  • Update the collectionView model easily.
  • Diffing data or sections (by using Dwifft)
  • Make easier building custom layout.
  • Well tested.

Collor Random Sample Collor Weather Sample

Getting started

Example

To run the example project, clone the repo, and run pod install from the Example directory first.
There are 4 examples:

  • Menu : Simple collectionView with userEvent propagation example
  • Random : Diffing entire data + custom layout
  • Weather : Diffing sections + custom layout
  • Pantone : Adding and remove items using CollectionDatas.

Usage

The UICollectionView is represented by a collectionData object which contains sectionDescriptors which contain themself cellDescriptors. Each item or cell in Collor is composed by 3 objects:

  • The UICollectionViewCell (XIB + swift file) which implements CollectionCellAdaptable
  • A cellDescriptor which implements CollectionCellDescribable
  • An adapter (view model) which implements CollectionAdapter
CellDescriptor

It describes the cell and is the link between the cell and the viewModel. Logically, one type of cell needs only one cellDescriptor. It owns the cell identifier, the cell className and handles the size of the cell. The collectionData handles cell registering and dequeuing using these properties.

final class WeatherDayDescriptor: CollectionCellDescribable {

    let identifier: String = "WeatherDayCollectionViewCell"
    let className: String = "WeatherDayCollectionViewCell"
    var selectable:Bool = false

    let adapter: WeatherDayAdapter

    init(adapter:WeatherDayAdapter) {
        self.adapter = adapter
    }

    func size(_ collectionView: UICollectionView, sectionDescriptor: CollectionSectionDescribable) -> CGSize {
        let sectionInset = sectionDescriptor.sectionInset(collectionView)
        let width:CGFloat = collectionView.bounds.width - sectionInset.left - sectionInset.right
        return CGSize(width:width, height:60)
    }

    public func getAdapter() -> CollectionAdapter {
        return adapter
    }
}
Adapter

An adapter is a viewModel object. It transforms your model in a human readable data used by the cell.

struct WeatherDayAdapter: CollectionAdapter {

    let date:NSAttributedString

    static let dateFormatter:DateFormatter = {
        let df = DateFormatter()
        df.dateFormat = "EEEE d MMMM"
        return df
    }()

    init(day:WeatherDay) {

        let dateString = WeatherDayAdapter.dateFormatter.string(from: day.date)
        date = NSAttributedString(string: dateString, attributes: [
            NSFontAttributeName: UIFont.boldSystemFont(ofSize: 18),
            NSForegroundColorAttributeName: UIColor.black
        ])
    }
}

When a cell is dequeued, the collectionData updates the cell with this object.

final class WeatherDayCollectionViewCell: UICollectionViewCell, CollectionCellAdaptable {
  @IBOutlet weak var label: UILabel!

  func update(with adapter: CollectionAdapter) {
        guard let adapter = adapter as? WeatherDayAdapter else {
            fatalError("WeatherDayAdapter required")
        }
        label.attributedText = adapter.date
    }
}
ViewController

Create the dataSource and the delegate:

lazy var collectionViewDelegate: CollectionDelegate = CollectionDelegate(delegate: self)
lazy var collectionViewDatasource: CollectionDataSource = CollectionDataSource(delegate: self)

Create the collectionData:

let collectionData = MyCollectionData()

Bind the collectionView with the data, the datasource and the delegate:

bind(collectionView: collectionView, with: collectionData, and: collectionViewDelegate, and: collectionViewDatasource)

Create a section and one cell in the collectionData:

final class MyCollectionData : CollectionData {

    override func reloadData() {
        super.reloadData()

        let section = MySectionDescriptor().reloadSection { (cells) in
                let cell = MyColorDescriptor(adapter: MyColorAdapter(model: "someThing"))
                cells.append(cell)
            })
        }
        sections.append(section)
    }
}

MySectionDescriptor:

final class MySectionDescriptor : CollectionSectionDescribable {

  func sectionInset(_ collectionView: UICollectionView) -> UIEdgeInsets {
      return UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 10)
  }
}

You get a readable data which represents your UICollectionView, without code duplication, reusing cell and with a good separation of code.

Diffing and updating

Collor provides some features to easily update your collectionData.

Updating

Just append or remove cells or sections using CollectionData.update(_:) method. This means an end to fiddling around with IndexPath:

let newCellDescriptor = NewCellDescriptor(...)
let result = collectionData.update { updater in
    updater.append(cells: [newCellDescriptor], after: anotherCellDescriptor)
}
collectionView.performUpdates(with: result)

Here is the list of all update methods available:

  • append(cells:after:)
  • append(cells:before:)
  • append(cells:in:)
  • remove(cells:)
  • reload(cells:)
  • append(sections:after:)
  • append(sections:before:)
  • append(sections:)
  • remove(sections:)
  • reload(sections:)
Diffing

Collor is using the great Dwifft library by Jack Flintermann for getting the "diff" between two updates of your collectionData.

  • Diffing some sections:
sectionDescriptor.isExpanded = !sectionDescriptor.isExpanded
let result = collectionData.update{ updater in
    updater.diff(sections: [sectionDescriptor])
}
collectionView.performUpdates(with: result)
  • Diffing entire data
model.someUpdates()
let result = collectionData.update { updater in
    collectionData.reload(model: model)
    updater.diff()
}
collectionView.performUpdates(with: result)

XCTemplates

Collor is published with 3 xctemplates for helping you creating ViewController, SectionDescriptor and CellDescriptor.

To install them, just go in xctemplates directory and run this command in a terminal:

sh install.sh

XCTemplates

Requirements

  • iOS 8.0+
  • Swift 3.0+
  • Xcode 8.0+

Installation

CocoaPods

Collor is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod "Collor"

Carthage

Collor doesn't yet support Carthage. Work in progress...

Documentation

Documentation

Work in progress... 1% documented

Credits

Collor is owned and maintained by Voyages-sncf.com.

Collor was originally created by Gwenn Guihal.

License

Collor is available under the BSD license. See the LICENSE file for more info.

collor's People

Contributors

gwennguihal avatar

Watchers

Carabineiro 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.