diff --git a/CheoMooRac/CheoMooRac/Sources/ViewControllers/MainViewController.swift b/CheoMooRac/CheoMooRac/Sources/ViewControllers/MainViewController.swift index 6d15c2e..a40fc4e 100644 --- a/CheoMooRac/CheoMooRac/Sources/ViewControllers/MainViewController.swift +++ b/CheoMooRac/CheoMooRac/Sources/ViewControllers/MainViewController.swift @@ -11,75 +11,37 @@ import UIKit import SnapKit import Then -class MainViewController: UIViewController { - - private let tableView = UITableView() - - private var filteredList: [String] = [] - private var arr = ["김윤서", "김루희", "윤예지", "김혜수", "코코", "민재", "잼권이", "리헤이", "노제", "몬익화", "립제이", "잘린이", "엠마", "모아나", "케이데이", "가비", "시미즈zz", "강호동", "이수근", "유재석", "리정" ] - - private var viewModel: MainViewModelProtocol = MainViewModel() - - private var isFiltering: Bool { - let searchController = self.navigationItem.searchController - let isActive = searchController?.isActive ?? false - let isSearchBarHasText = searchController?.searchBar.text?.isEmpty == false - return isActive && isSearchBarHasText - } - - private var sectionHeaderList: [String] { - var sectionHeaderList: [String] = [] - - arr.forEach { name in - sectionHeaderList.append(StringManager.shared.chosungCheck(word: name)) - } - - return Array(Set(sectionHeaderList)).sorted() +extension UIViewController { + func embed(_ viewController: UIViewController) { + viewController.willMove(toParent: self) + self.addChild(viewController) + viewController.didMove(toParent: self) } +} + + +class MainViewController: UIViewController { - private var filterdHeaderList: [String] = [] + var tableViewController: MainTableViewController! -// init(with viewModel: MainViewModel) { -// self.viewModel = viewModel -// super.init(nibName: nil, bundle: nil) -// } -// -// required init?(coder: NSCoder) { -// fatalError("init(coder:) has not been implemented") -// } -// override func viewDidLoad() { super.viewDidLoad() + let mainViewModel = MainViewModel() + self.tableViewController = MainTableViewController(with: mainViewModel) initViewController() setLayouts() - setTableView() - setRefreshControl() - } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) setSearchController() } - - private func bindViewModel() { - viewModel.list.bind { [weak self] _ in - guard let self = self else {return} - self.tableView.reloadData() - } - } private func initViewController() { title = "연락처" view.backgroundColor = .white } - private func setRefreshControl() { - let refresh = UIRefreshControl() - refresh.addTarget(self, action: #selector(tableViewDidPulled(refresh:)), for: .valueChanged) - tableView.refreshControl = refresh - } - private func setSearchController() { let searchController = UISearchController(searchResultsController: nil) navigationItem.searchController = searchController @@ -93,24 +55,18 @@ class MainViewController: UIViewController { searchController.searchResultsUpdater = self } - private func setTableView() { - tableView.delegate = self - tableView.dataSource = self - - tableView.registerReusableCell(MyCardTableViewCell.self) - } - private func setLayouts() { setViewHierarchy() setConstraints() } private func setViewHierarchy() { - view.addSubview(tableView) + embed(tableViewController) + view.addSubview(tableViewController.view) } private func setConstraints() { - tableView.snp.makeConstraints { + tableViewController.view.snp.makeConstraints { $0.edges.equalToSuperview() } } @@ -124,102 +80,11 @@ extension MainViewController { let navCreateViewController: UINavigationController = UINavigationController(rootViewController: createViewController) present(navCreateViewController, animated: true, completion: nil) } - - @objc - private func tableViewDidPulled(refresh: UIRefreshControl) { - refresh.endRefreshing() - tableView.reloadData() - } -} - -extension MainViewController: UITableViewDelegate { - func numberOfSections(in tableView: UITableView) -> Int { - return viewModel.sectionHeaderList.value.count -// return isFiltering ? filterdHeaderList.count + 1 : sectionHeaderList.count + 1 - } - - func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { - switch indexPath.section { - case 0: - return 100 - default: - return 48 - } - } - - func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - tableView.deselectRow(at: indexPath, animated: true) - navigationController?.pushViewController(ReadViewController(), animated: true) - } -} - -extension MainViewController: UITableViewDataSource { - func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - switch section { - case 0 : - return self.isFiltering ? 0 : 1 - default: - return self.isFiltering ? getSectionArray(at: section, list: viewModel.list.value).count: getSectionArray(at: section, list: viewModel.list.value).count - } - } - - func getSectionArray(at section: Int, list: [String]) -> [String] { - return list.filter { - return StringManager.shared.chosungCheck(word: $0) == sectionHeaderList[section-1] - } - } - - func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - switch indexPath.section { - case 0: - let cell = tableView.dequeueReusableCell(indexPath: indexPath) as MyCardTableViewCell - return cell - - case 1...sectionHeaderList.count: - let cell = UITableViewCell() - - if self.isFiltering { - cell.textLabel?.text = getSectionArray(at: indexPath.section,list: viewModel.list.value)[indexPath.row] - } else { - cell.textLabel?.text = getSectionArray(at: indexPath.section,list: viewModel.list.value)[indexPath.row] - } - - return cell - - default: - return UITableViewCell() - } - } - - func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { - if section != 0 { - return isFiltering ? viewModel.sectionHeaderList.value[section-1] : viewModel.sectionHeaderList.value[section-1] - } else { - return nil - } - } - - func sectionIndexTitles(for tableView: UITableView) -> [String]? { - return viewModel.sectionHeaderList.value - } - } extension MainViewController: UISearchResultsUpdating{ func updateSearchResults(for searchController: UISearchController) { guard let text = searchController.searchBar.text else { return } - filterdHeaderList.removeAll() - filteredList.removeAll() - - filteredList = arr.filter { $0.localizedCaseInsensitiveContains(text) } - filteredList.forEach { name in - filterdHeaderList.append(StringManager.shared.chosungCheck(word: name)) - } - - filterdHeaderList = Array(Set(filterdHeaderList)).sorted() - - dump(filteredList) - - tableView.reloadData() + } } diff --git a/CheoMooRac/CheoMooRac/Sources/ViewModels/MainViewModel.swift b/CheoMooRac/CheoMooRac/Sources/ViewModels/MainViewModel.swift index 21ac60f..6c88b75 100644 --- a/CheoMooRac/CheoMooRac/Sources/ViewModels/MainViewModel.swift +++ b/CheoMooRac/CheoMooRac/Sources/ViewModels/MainViewModel.swift @@ -8,21 +8,43 @@ import Foundation protocol MainViewModelInput { - + func refreshTableView() } protocol MainViewModelOutput { var list: Dynamic<[String]> {get} var sectionHeaderList: Dynamic<[String]> {get} + var nowRefreshing: Dynamic {get} + var sectionArray: Dynamic<[String]> {get} + func getSectionArray(at section: Int) -> Dynamic<[String]> } protocol MainViewModelProtocol : MainViewModelInput,MainViewModelOutput {} class MainViewModel: MainViewModelProtocol { + // MARK: - INPUT + func refreshTableView() { + if !nowRefreshing.value { + nowRefreshing.value = true + //refreshing logic + nowRefreshing.value = false + } + } + // MARK: - OUTPUT let list: Dynamic<[String]> = Dynamic([]) let sectionHeaderList: Dynamic<[String]> = Dynamic([]) + let nowRefreshing: Dynamic = Dynamic(false) + let sectionArray: Dynamic<[String]> = Dynamic([]) + + func getSectionArray(at section: Int) -> Dynamic<[String]> { + + let list$ = self.list.value.filter { + return StringManager.shared.chosungCheck(word: $0) == sectionHeaderList.value[section-1] + } + return Dynamic(list$) + } // private var filteredList: [String] = [] // private var filterdHeaderList: [String] = [] diff --git a/CheoMooRac/CheoMooRac/Sources/Views/MainTableViewController.swift b/CheoMooRac/CheoMooRac/Sources/Views/MainTableViewController.swift index 197e10b..131c92e 100644 --- a/CheoMooRac/CheoMooRac/Sources/Views/MainTableViewController.swift +++ b/CheoMooRac/CheoMooRac/Sources/Views/MainTableViewController.swift @@ -19,5 +19,98 @@ class MainTableViewController: UITableViewController { fatalError("init(coder:) has not been implemented") } + override func viewDidLoad() { + super.viewDidLoad() + bindViewModel() + setTableView() + setRefreshControl() + } + + private func setTableView() { + tableView.registerReusableCell(MyCardTableViewCell.self) + } + + private func bindViewModel() { + viewModel.list.bind { [weak self] _ in + guard let self = self else {return} + self.tableView.reloadData() + } + + viewModel.nowRefreshing.bind { [weak self] _ in + guard let self = self else {return} + self.refreshControl?.endRefreshing() + } + } + + private func setRefreshControl() { + let refresh = UIRefreshControl() + refresh.addTarget(self, action: #selector(tableViewDidPulled(refresh:)), for: .valueChanged) + tableView.refreshControl = refresh + } +} + +extension MainTableViewController { + @objc + private func tableViewDidPulled(refresh: UIRefreshControl) { + viewModel.refreshTableView() + } +} + +extension MainTableViewController { + override func numberOfSections(in tableView: UITableView) -> Int { + return viewModel.sectionHeaderList.value.count + 1 + } + override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + tableView.deselectRow(at: indexPath, animated: true) + navigationController?.pushViewController(ReadViewController(), animated: true) + } + + override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + switch indexPath.section { + case 0: + return 100 + default: + return 48 + } + } +} + +extension MainTableViewController { + override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + switch section { + case 0: + return 1 + default: + return viewModel.getSectionArray(at: section).value.count + } + } + + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + switch indexPath.section { + case 0: + let cell = tableView.dequeueReusableCell(indexPath: indexPath) as MyCardTableViewCell + return cell + + case 1...viewModel.sectionHeaderList.value.count: + let cell = UITableViewCell() + cell.textLabel?.text = viewModel.getSectionArray(at: indexPath.section).value[indexPath.row] + return cell + + default: + return UITableViewCell() + } + } + + override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { + if section != 0 { + return viewModel.sectionHeaderList.value[section - 1] + } else { + return nil + } + } + + override func sectionIndexTitles(for tableView: UITableView) -> [String]? { + return viewModel.sectionHeaderList.value + } }