Git Product home page Git Product logo

tableandcollectionviewextensions's Introduction

Improving Table View and Collection View APIs

TLDR

1. Registering cells

tableView.register(UINib(nibName: "TableViewCell",
                   bundle: Bundle(for: type(of: self))), forCellReuseIdentifier: "TableViewCell")

vs

tableView.register(TableViewCell.self)

2. Dequeueing cells

tableView.dequeueReusableCell(withIdentifier: "TableViewCell", for: indexPath)

vs

tableView.dequeue(TableViewCell.self, indexPath: indexPath)

Protocols

1. ReuseIdentifiable

Implementation

  • reuseID - returns the name of the class
protocol ReuseIdentifiable {
    static var reuseID: String { get }
}

extension ReuseIdentifiable {
    static var reuseID: String { return String(describing: self) }
}

Usage

class TableViewCell: UITableViewCell, ReuseIdentifiable {}
class CollectionViewCell: UICollectionViewCell, ReuseIdentifiable {}

2. NibLoadable

Implementation

  • nib - returns a UINib using the reuseID and the bundle of the class
  protocol NibLoadable: class {
      static var nib: UINib { get }
  }

  extension NibLoadable where Self: ReuseIdentifiable {
      static var nib: UINib {
          return UINib(nibName: reuseID, bundle: Bundle(for: Self.self))
      }
  }

Usage

  class TableViewCell: UITableViewCell, NibLoadable, ReuseIdentifiable {}
  class CollectionViewCell: UICollectionViewCell, NibLoadable, ReuseIdentifiable {}

Safer Table View and Collection View

1. Registering cells

Implementation

๐ŸŽ's API

To register a nib, we normally pass string literals for the nib name and reuseIdentifier.

  tableView.register(UINib(nibName: "TableViewCell",
                     bundle: Bundle(for: type(of: self))),
                     forCellReuseIdentifier: "TableViewCell")
Cleaner way

Create a convenience method that takes in a cell that adopts both NibLoadable & ReuseIdentifiable. We can then use the nib and reuseID properties to register the cell

  func register<T: NibLoadable & ReuseIdentifiable>(_ cellClass: T.Type) {
    register(cellClass.nib, forCellReuseIdentifier: cellClass.reuseID)
  }

Usage

  tableView.register(TableViewCell.self)

2. Dequeueing cells

Implementation

๐ŸŽ's API

To dequeue a cell, we need to pass in the cell's reuse identifier. Again, we would normal just pass in a string literal

  tableView.dequeueReusableCell(withIdentifier: "TableViewCell", for: indexPath)

Cleaner way

Create a convenience method that takes in a cell that adopts ReuseIdentifiable. We then use the reuseID property when dequeueing a cell

  func dequeue<T: ReuseIdentifiable>(_ cellClass: T.Type, indexPath: IndexPath) -> T {
    return dequeueReusableCell(withIdentifier: cellClass.reuseID, for: indexPath) as! T
  }

Usage

  tableView.dequeue(TableViewCell.self, indexPath: indexPath)

Extending Table View and Collection View

Implementation

extension UITableView {
    func register<T: NibLoadable & ReuseIdentifiable>(_ cellClass: T.Type) {
        register(cellClass.nib, forCellReuseIdentifier: cellClass.reuseID)
    }

    func dequeue<T: ReuseIdentifiable>(_ cellClass: T.Type, indexPath: IndexPath) -> T {
        return dequeueReusableCell(withIdentifier: cellClass.reuseID, for: indexPath) as! T
    }
}

extension UICollectionView {
    func register<T: NibLoadable & ReuseIdentifiable>(_ cellClass: T.Type) {
        register(cellClass.nib, forCellWithReuseIdentifier: cellClass.reuseID)
    }

    func dequeue<T: ReuseIdentifiable>(_ cellClass: T.Type, indexPath: IndexPath) -> T {
        return dequeueReusableCell(withReuseIdentifier: cellClass.reuseID, for: indexPath) as! T
    }
}

Usage

class TableViewCell: UITableViewCell, NibLoadable, ReuseIdentifiable {}
class CollectionViewCell: UICollectionViewCell, NibLoadable, ReuseIdentifiable {}

//Register
tableView.register(TableViewCell.self)
collectionView.register(CollectionViewCell.self)

//Dequeue
let cvCell = tableView.dequeue(TableViewCell.self, indexPath: indexPath)
let tvCell = collectionView.dequeue(CollectionViewCell.self, indexPath: indexPath)

tableandcollectionviewextensions's People

Contributors

kidap avatar

Watchers

James Cloos 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.