diff --git a/SwiftyViewModels.xcodeproj/project.xcworkspace/xcuserdata/mattbaranowski.xcuserdatad/UserInterfaceState.xcuserstate b/SwiftyViewModels.xcodeproj/project.xcworkspace/xcuserdata/mattbaranowski.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..5d93e9c Binary files /dev/null and b/SwiftyViewModels.xcodeproj/project.xcworkspace/xcuserdata/mattbaranowski.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/SwiftyViewModels/CellViewModels.swift b/SwiftyViewModels/CellViewModels.swift index 84f03bf..466685c 100644 --- a/SwiftyViewModels/CellViewModels.swift +++ b/SwiftyViewModels/CellViewModels.swift @@ -9,15 +9,38 @@ import Foundation import UIKit -protocol CellViewModelType { } +protocol AnyCellViewModelType { + var reuseIdentifier: String { get } +} + +protocol CellViewModelType: AnyCellViewModelType { + associatedtype CellType: AnyCellConfigurable +} -protocol CellConfigurable { +extension CellViewModelType { + var reuseIdentifier: String { + return CellType.self.reuseIdentifier + } +} + +protocol AnyCellConfigurable: NibLoadable { + func configure(with viewModel: AnyCellViewModelType) +} + +protocol CellConfigurable: AnyCellConfigurable { associatedtype ViewModelType: CellViewModelType func configure(with viewModel: ViewModelType) } -struct KeyBoardCellViewModel: CellViewModelType { +extension CellConfigurable { + func configure(with viewModel: AnyCellViewModelType) { + configure(with: viewModel as! ViewModelType) + } +} +struct KeyBoardCellViewModel: CellViewModelType { + typealias CellType = KeyboardTableViewCell + let titleField: String let synthesizerField: String let numberOfKeyField: String @@ -32,7 +55,8 @@ struct KeyBoardCellViewModel: CellViewModelType { } struct GuitarCellViewModel: CellViewModelType { - + typealias CellType = GuitarTableViewCell + let titleField: String let stringField: String let image: UIImage @@ -52,7 +76,8 @@ struct GuitarCellViewModel: CellViewModelType { } struct AccessoryViewModel: CellViewModelType { - + typealias CellType = AccessoryItemTableViewCell + let titleField: String let detailField: String let image: UIImage diff --git a/SwiftyViewModels/InstrumentViewController.swift b/SwiftyViewModels/InstrumentViewController.swift index 163efac..c23e3c1 100644 --- a/SwiftyViewModels/InstrumentViewController.swift +++ b/SwiftyViewModels/InstrumentViewController.swift @@ -25,9 +25,9 @@ class InstrumentViewController: UIViewController { } func registerCells() { - tableView.register(cell: GuitarTableViewCell.self) - tableView.register(cell: KeyboardTableViewCell.self) - tableView.register(cell: AccessoryItemTableViewCell.self) + for cellType in InstrumentViewModel.cellTypes { + tableView.register(cell: cellType) + } } } @@ -42,15 +42,9 @@ extension InstrumentViewController: UITableViewDataSource { } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - - let cellType = viewModel.cellType(for: indexPath) - let cell = tableView.dequeueReusableCell(withIdentifier: cellType.reuseIdentifier, for: indexPath) - let cellViewModel = viewModel.viewModel(for: indexPath) - - configureCell(cell, cellViewModel: cellViewModel) - - + let cell = tableView.dequeueReusableCell(withIdentifier: cellViewModel.reuseIdentifier, for: indexPath) + (cell as! AnyCellConfigurable).configure(with: cellViewModel) return cell } @@ -58,22 +52,6 @@ extension InstrumentViewController: UITableViewDataSource { func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return 128.0 } - - func configureCell(_ cell: UITableViewCell, cellViewModel: CellViewModelType) { - - switch (cell, cellViewModel) { - case (let cell as GuitarTableViewCell, let cellViewModel as GuitarCellViewModel): - cell.configure(with: cellViewModel) - case (let cell as KeyboardTableViewCell, let cellViewModel as KeyBoardCellViewModel): - cell.configure(with: cellViewModel) - case (let cell as AccessoryItemTableViewCell, let cellViewModel as AccessoryViewModel): - cell.configure(with: cellViewModel) - default: - fatalError("Mismatched cell and view model") - - } - - } } extension InstrumentViewController: UITableViewDelegate { diff --git a/SwiftyViewModels/InstrumentViewModel.swift b/SwiftyViewModels/InstrumentViewModel.swift index 9b4b9b8..e5ed013 100644 --- a/SwiftyViewModels/InstrumentViewModel.swift +++ b/SwiftyViewModels/InstrumentViewModel.swift @@ -23,6 +23,12 @@ struct InstrumentViewModel { let keyboardViewModels: [KeyBoardCellViewModel] let accessoryViewModels: [AccessoryViewModel] + static let cellTypes: [AnyCellConfigurable.Type] = [ + GuitarTableViewCell.self, + KeyboardTableViewCell.self, + AccessoryItemTableViewCell.self + ] + var sectionCount: Int { return Section.all.count } @@ -48,7 +54,7 @@ struct InstrumentViewModel { } } - func viewModel(for indexPath: IndexPath) -> CellViewModelType { + func viewModel(for indexPath: IndexPath) -> AnyCellViewModelType { guard let section = Section(rawValue: indexPath.section) else { fatalError("Invalid section") } @@ -63,19 +69,4 @@ struct InstrumentViewModel { } } - - func cellType(for indexPath: IndexPath) -> NibLoadable.Type { - guard let section = Section(rawValue: indexPath.section) else { - fatalError("Invalid section") - } - - switch section { - case .guitar: - return GuitarTableViewCell.self - case .keyboard: - return KeyboardTableViewCell.self - case .accessory: - return AccessoryItemTableViewCell.self - } - } }