Skip to content

GenericTableView with Examples (Simple - Dynamic - Testable)

Notifications You must be signed in to change notification settings

meguid/GenericTableView

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 

Repository files navigation

GenericTableView

GenericTableView with Examples (Simple - Dynamic - Testable)

Goals:

  • Generic TableView Data Source / Delegate
  • Dynamic TableView (Depends on protocols)
  • Reusable TableView (We don't need storyboards for tableview, we only need xib files for cells)
  • Better TableView Testability (The tableview will be generic and has zero business logic)
  • Better Cells Testability (The cells will be depending on the Item -which is testable- for the logic)
  • More...

Usage

  • Adding the tableview would be like this

    let users = [UsersDataSource(user: User(firstname: "Adam", lastname: "Meguid")),
                 UsersDataSource(user: User(firstname: "Ahmed", lastname: "Ali"))]
    
    func addTableView() {
        let usersList = GenericTableView(frame: view.bounds)
        usersList.updateDataSource(items: users)
        self.view.addSubview(usersList)
    }

    But first we need to add 3 things

    • Model
    struct User: GenericModel {
      var firstname: String
      var lastname: String
    } 
    • Cell
    class UserCell: UITableViewCell, GenericCell {
      @IBOutlet weak var firstname: UILabel!
      @IBOutlet weak var lastname: UILabel!
    
      func configure(model: GenericModel) {
          if let user = model as? User {
              firstname.text = user.firstname
              lastname.text = user.lastname
          }
      }
    }
    • Data Source
    class UsersDataSource: GenericDataSource {
    
      var type: UITableViewCell.Type = UserCell.self
      var action: (GenericModel) -> () = {_ in }
      var item: GenericModel
    
      init(user: User) {
          item = user
      }
    } 

And that's all you need.

More Customization

  • Adding actions to cell selection

    func addTableView() {
        .
        .
        users.forEach({$0.action = navigateToUserView()})
        .
    }
    
    private func navigateToUserView() -> (GenericModel) -> Void {
        return { (user: GenericModel) in
            // here navigate to $user view
        }
    }
  • Supporting Multi Actions

    func addTableView() {
        .
        users.forEach { (user) in
            if let userItem = user.item as? User {
                if userItem.activated {
                    user.action = navigateToUserView()
                } else {
                    user.action = blockUserAccess()
                }
            }
        }
        .
        .
    }
    
    private func navigateToUserView() -> (GenericModel) -> Void {
        return { (user: GenericModel) in
            // here navigate to $user view
        }
    }
    
    private func blockUserAccess() -> (GenericModel) -> Void {
        return { (user: GenericModel) in
            // here block access to $user
        }
    }
    
    struct User: GenericModel {
      .
      .
      var activated: Bool
    }
  • Supporting Multi Cells with Multi Actions

    let users = [UsersDataSource(user: User(firstname: "Adam", lastname: "Meguid")),
                 PremiumUsersDataSource(user: PremiumUser(firstname: "Ahmed", lastname: "Ali", grade: "Class A"))]
    
    struct PremiumUser: GenericModel {
        var firstname: String
        var lastname: String
        var grade: String
    }
    
    class PremiumUserCell: UserCell {
        @IBOutlet weak private var grade: UILabel!
    
        override func configure(model: GenericModel) {
            if let user = model as? PremiumUser {
                firstname.text = user.firstname
                lastname.text = user.lastname
                grade.text = user.grade
            }
        }
    }
    
    class PremiumUsersDataSource: GenericDataSource {
    
      var type: UITableViewCell.Type = PremiumUserCell.self
      var action: (GenericModel) -> () = {_ in }
      var item: GenericModel
    
      init(user: PremiumUserCell) {
          item = user
      }
    } 

About

GenericTableView with Examples (Simple - Dynamic - Testable)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages