Skip to content

Instantly share code, notes, and snippets.

@pavankataria
Created October 6, 2017 13:54
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save pavankataria/193a929de8525ac5744afe28158516c5 to your computer and use it in GitHub Desktop.
Save pavankataria/193a929de8525ac5744afe28158516c5 to your computer and use it in GitHub Desktop.
Injecting View into Generic TableViewCell
import Foundation
import UIKit
public protocol CellRepresentable {
static func registerCell(tableView: UITableView)
func dequeueCell(tableView: UITableView, indexPath: IndexPath) -> UITableViewCell
func cellSelected(_ indexPath: IndexPath)
}
//MARK: - Default Implementation
class TitleView: UIView {
let label = UILabel()
override init(frame: CGRect) {
super.init(frame: frame)
configure()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
configure()
}
private func configure() {
backgroundColor = .red
addSubview(label)
}
override func layoutSubviews() {
super.layoutSubviews()
label.frame = bounds
}
}
extension TitleView {
func setup(_ viewModel: TitleViewCellViewModel){
self.label.text = viewModel.title
}
}
class ButtonView: UIView {
let button = UIButton()
var didPressButtonEvent: (() -> Void)?
override init(frame: CGRect) {
super.init(frame: frame)
configure()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
configure()
}
private func configure() {
backgroundColor = .green
button.addTarget(self, action: #selector(self.didPressButton), for: .touchUpInside)
button.backgroundColor = .cyan
addSubview(button)
}
override func layoutSubviews() {
super.layoutSubviews()
button.frame = bounds
}
@objc func didPressButton(){
self.didPressButtonEvent?()
}
}
extension ButtonView {
func setup(_ viewModel: ButtonViewCellViewModel){
self.button.setTitle(viewModel.title, for: .normal)
self.didPressButtonEvent = viewModel.didPressEvent
}
}
class ButtonViewCellViewModel {
var title: String
var didPressEvent: (() -> Void)?
init(title: String, handler: (() -> Void)?){
self.title = title
self.didPressEvent = handler
}
}
extension ButtonViewCellViewModel: CellRepresentable {
private struct Properties {
static let identifier = “CustomCellButtonView”
}
static func registerCell(tableView: UITableView) {
tableView.register(CustomCell<ButtonView>.self, forCellReuseIdentifier: Properties.identifier)
}
func dequeueCell(tableView: UITableView, indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: Properties.identifier, for: indexPath) as? CustomCell<ButtonView> else {
fatalError()
}
cell.customView.setup(self)
return cell
}
func cellSelected(_ indexPath: IndexPath) {
}
}
//MARK: - TitleViewCellViewModel setup
class TitleViewCellViewModel {
let title: String
init(title: String){
self.title = title
}
}
extension TitleViewCellViewModel: CellRepresentable {
private struct Properties {
static let identifier = “CustomCellTitleView”
}
static func registerCell(tableView: UITableView) {
tableView.register(CustomCell<TitleView>.self, forCellReuseIdentifier: Properties.identifier)
}
func dequeueCell(tableView: UITableView, indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: Properties.identifier, for: indexPath) as? CustomCell<TitleView> else {
fatalError()
}
cell.customView.setup(self)
return cell
}
func cellSelected(_ indexPath: IndexPath) {
}
}
class CustomCell<View: UIView>: UITableViewCell {
let customView = View(frame: .zero)
override func layoutSubviews() {
super.layoutSubviews()
contentView.addSubview(customView)
customView.frame = contentView.bounds
}
}
class VCViewModel {
let cellViewModelTypes: [CellRepresentable.Type] = [
TitleViewCellViewModel.self,
ButtonViewCellViewModel.self
]
var cellViewModels = [CellRepresentable]()
init(){
self.cellViewModels = self.createCellViewModels()
}
func createCellViewModels() -> [CellRepresentable] {
var cells = [CellRepresentable]()
let titleCellViewModel = TitleViewCellViewModel(title: “Fuck yeah”)
cells.append(titleCellViewModel)
let buttonCellViewModel = ButtonViewCellViewModel(title: “Click me”){
print(“did press button”)
}
cells.append(buttonCellViewModel)
return cells
}
}
class VC: UIViewController, UITableViewDataSource, UITableViewDelegate {
private let tableView = UITableView()
private let vCViewModel = VCViewModel()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
view.addSubview(tableView)
tableView.dataSource = self
tableView.delegate = self
vCViewModel.cellViewModelTypes.forEach { $0.registerCell(tableView: tableView) }
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
tableView.frame = view.bounds
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.vCViewModel.cellViewModels.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
return self.vCViewModel.cellViewModels[indexPath.row].dequeueCell(tableView: tableView, indexPath: indexPath)
}
}
import PlaygroundSupport
let vc = VC()
PlaygroundPage.current.liveView = vc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment