Latest 0.0.1
License Apache 2.0
Platforms ios 9.0
Dependencies IGListKit




MenuListKit provides a fast way to create lists and menus with declarative programming in Swift. It’s a thin abstraction layer over the powerful IGListKit.

🚀 Declaratively define lists and menu
🙏🏻 The code reflects the UI
📁 Less code and less files to manage
⚡️ No performance impact
🔋 Efficient cell updates thanks to ListDiffable by IGListKit

The idea of MenuListKit is to provide a declarative way to create menus in iOS without writing boilerplate code. With MenuListKit you can focus better on the architecture and the business logic of your app 👍🏻

You won’t lose time writing the same error-prone boilerplate code 💩.

The final result is more maintainable and modular codebase ✅.

Give it a shot and see the difference 🎉!

In the example below there’s a classic and simple ToDo List app; as you can see the array of models reflects the cells in the UICollectionView. This will make you code more explicit and readable.


  • iOS 9.0+
  • Swift 4.0+
  • Xcode 9.0+



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

pod 'MenuListKit'


Define your MenuItem

The first thing to do is to create a UICollectionViewCell with a custom UI. You can both create a cell programmatically or load it from a xib.

class ToDoCell: UICollectionViewCell {

    @IBOutlet private weak var statusLabel: UILabel!
    @IBOutlet private weak var textLabel: UILabel!

    var text: String? {
        get { return textLabel.text }
        set { textLabel.text = newValue }

    var isCompleted: Bool = false {
        didSet {
            statusLabel.text = isCompleted ? "✅" : "⏺"

    override func awakeFromNib() {
        isCompleted = false


In MenuListKit every cell is represented by a MenuItem object. The MenuItem class is a "model representation" of your cell. It contains all the information to configure the UICollectionViewCell view.

Create your item class that inherits from MenuItem and implements ListDiffable (from IGListKit).

Remember to add import IGListKit at the top

import MenuListKit
import IGListKit

class ToDoItem: MenuItem<ToDoCell>, ListDiffable {

    let uuid = UUID().uuidString
    var text: String
    var isCompleted: Bool

    init(text: String, isCompleted: Bool) {
        self.text = text
        self.isCompleted = isCompleted
        super.init(bundle: Bundle.main,
                   height: 55,
                   actionDelegate: nil)

    override func bind(to cell: ToDoCell) {
        cell.text = text
        cell.isCompleted = isCompleted

    // MARK: - ListDiffable

    func diffIdentifier() -> NSObjectProtocol {
        return uuid as NSObjectProtocol

    func isEqual(toDiffableObject object: ListDiffable?) -> Bool {
        if let object = object as? ToDoItem {
            return object.text == text && object.isCompleted == isCompleted
        return false


MenuAdapterItem and data source

To load an array of models into a UICollectionView, we’ve reused the idea of IGListKit and we’ve created the MenuListAdapter.

To all get the work done, implement the data source protocol MenuListAdapterDataSource to provide the array of models to the collectionView. The adapter will manage all insertions, deletions and updates based on the array.
You can also provide an UIView to present when there’s no data to show.

import MenuListKit
import IGListKit

class ToDoViewController: UIViewController {

    let collectionView = UICollectionView(frame: .zero, 
                                          collectionViewLayout: UICollectionViewFlowLayout())

    lazy var adapter: MenuListAdapter = {
        return MenuListAdapter(viewController: self)

    let todos = [

        ToDoItem(text: "Clean up my room", isCompleted: false),
        ToDoItem(text: "Buy 3 apples", isCompleted: true),
        ToDoItem(text: "Plan my next trip", isCompleted: true),
        ToDoItem(text: "Book a hotel room in Rome", isCompleted: false)


    override func viewDidLoad() {

        collectionView.backgroundColor = .white

        adapter.collectionView = collectionView
        adapter.dataSource = self

    override func viewDidLayoutSubviews() {
        collectionView.frame = view.bounds


// MARK: - MenuListAdapterDataSource

extension ToDoViewController: MenuListAdapterDataSource {

    func objects(for menuListAdapter: MenuListAdapter) -> [ListDiffable & BaseMenuItem] {
        return todos

    func emptyView(for menuListAdapter: MenuListAdapter) -> UIView? {
        return nil


More resources

About us

We’re 3 friends who love to work on open source projects 💙.

Get in touch with us saying hi 👋🏻 at [email protected]. We’re also on Medium 🖊


Feel free to collaborate with ideas, issues and/or pull requests.

P.S. If you use MenuListKit in your app we would love to hear about it! 😉


MenuListKit is available under the Apache 2.0 license. See the LICENSE file for more info.

Latest podspec

    "name": "MenuListKit",
    "version": "0.0.1",
    "summary": "A fast way to create lists and menus in Swift",
    "description": "A fast way to create lists and menus with declarative programming in Swift",
    "homepage": "",
    "license": "Apache 2.0",
    "authors": {
        "mooncoders": "[email protected]"
    "source": {
        "git": "",
        "tag": "0.0.1"
    "platforms": {
        "ios": "9.0"
    "source_files": "MenuListKit/Classes/**/*",
    "dependencies": {
        "IGListKit": [
            "~> 3.0.0"
    "pushed_with_swift_version": "4.0"

Pin It on Pinterest

Share This