// This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. import UIKit import SnapKit class StaticTableController: UIViewController { fileprivate let theme: Theme fileprivate let tableViewStyle: UITableViewStyle fileprivate var modelArray: [[StaticTableBaseCellModel]] fileprivate let footerArray: [String?]? fileprivate var tableView: UITableView? init(theme: Theme, style: UITableViewStyle, model: [[StaticTableBaseCellModel]], footers: [String?]? = nil) { self.theme = theme self.tableViewStyle = style self.modelArray = model self.footerArray = footers super.init(nibName: nil, bundle: nil) edgesForExtendedLayout = UIRectEdge() } required convenience init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func loadView() { loadViewWithBackgroundColor(theme.colorForType(.NormalBackground)) createTableView() installConstraints() } func reloadTableView() { tableView?.reloadData() } func updateModelArray(_ model: [[StaticTableBaseCellModel]]) { modelArray = model reloadTableView() } } extension StaticTableController: UITableViewDataSource { func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let model = modelArray[indexPath.section][indexPath.row] let cell: StaticTableBaseCell switch model { case _ as StaticTableButtonCellModel: cell = dequeueCellForClass(StaticTableButtonCell.staticReuseIdentifier) case _ as StaticTableAvatarCellModel: cell = dequeueCellForClass(StaticTableAvatarCell.staticReuseIdentifier) case _ as StaticTableDefaultCellModel: cell = dequeueCellForClass(StaticTableDefaultCell.staticReuseIdentifier) case _ as StaticTableChatButtonsCellModel: cell = dequeueCellForClass(StaticTableChatButtonsCell.staticReuseIdentifier) case _ as StaticTableSwitchCellModel: cell = dequeueCellForClass(StaticTableSwitchCell.staticReuseIdentifier) case _ as StaticTableInfoCellModel: cell = dequeueCellForClass(StaticTableInfoCell.staticReuseIdentifier) case _ as StaticTableMultiChoiceButtonCellModel: cell = dequeueCellForClass(StaticTableMultiChoiceButtonCell.staticReuseIdentifier) default: fatalError("Static model class \(model) has not been implemented") } cell.setupWithTheme(theme, model: model) let isLastRow = (indexPath.row == (modelArray[indexPath.section].count - 1)) let isLastSection = (indexPath.section == (modelArray.count - 1)) switch tableViewStyle { case .plain: cell.setBottomSeparatorHidden(!isLastRow || isLastSection) case .grouped: cell.setBottomSeparatorHidden(isLastRow) case .insetGrouped: print("error") } return cell } func numberOfSections(in tableView: UITableView) -> Int { return modelArray.count } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return modelArray[section].count } func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? { guard let array = footerArray else { return nil } guard section < array.count else { return nil } return array[section] } } extension StaticTableController: UITableViewDelegate { func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { tableView.deselectRow(at: indexPath, animated: true) guard let cell = tableView.cellForRow(at: indexPath) as? StaticTableBaseCell else { return } let model = modelArray[indexPath.section][indexPath.row] switch model { case let model as StaticTableSelectableCellModel: model.didSelectHandler?(cell) default: // nop break; } } } private extension StaticTableController { func createTableView() { tableView = UITableView(frame: CGRect.zero, style: tableViewStyle) tableView!.dataSource = self tableView!.delegate = self tableView!.estimatedRowHeight = 44.0; tableView!.separatorStyle = .none; switch tableViewStyle { case .plain: tableView!.backgroundColor = theme.colorForType(.NormalBackground) case .grouped: tableView!.backgroundColor = theme.colorForType(.SettingsBackground) case .insetGrouped: print("error") } view.addSubview(tableView!) tableView!.register(StaticTableButtonCell.self, forCellReuseIdentifier: StaticTableButtonCell.staticReuseIdentifier) tableView!.register(StaticTableAvatarCell.self, forCellReuseIdentifier: StaticTableAvatarCell.staticReuseIdentifier) tableView!.register(StaticTableDefaultCell.self, forCellReuseIdentifier: StaticTableDefaultCell.staticReuseIdentifier) tableView!.register(StaticTableChatButtonsCell.self, forCellReuseIdentifier: StaticTableChatButtonsCell.staticReuseIdentifier) tableView!.register(StaticTableSwitchCell.self, forCellReuseIdentifier: StaticTableSwitchCell.staticReuseIdentifier) tableView!.register(StaticTableInfoCell.self, forCellReuseIdentifier: StaticTableInfoCell.staticReuseIdentifier) tableView!.register(StaticTableMultiChoiceButtonCell.self, forCellReuseIdentifier: StaticTableMultiChoiceButtonCell.staticReuseIdentifier) } func installConstraints() { tableView!.snp.makeConstraints { $0.edges.equalTo(view) } } func dequeueCellForClass(_ identifier: String) -> StaticTableBaseCell { return tableView!.dequeueReusableCell(withIdentifier: identifier) as! StaticTableBaseCell } }