Skip to content

Commit

Permalink
[#4] view, viewcontroller 분리
Browse files Browse the repository at this point in the history
  • Loading branch information
ezidayzi committed Sep 24, 2021
1 parent 3139043 commit 6cb50aa
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 152 deletions.
167 changes: 16 additions & 151 deletions CheoMooRac/CheoMooRac/Sources/ViewControllers/MainViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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()
}
}
Expand All @@ -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()

}
}
24 changes: 23 additions & 1 deletion CheoMooRac/CheoMooRac/Sources/ViewModels/MainViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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<Bool> {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<Bool> = 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] = []
Expand Down
93 changes: 93 additions & 0 deletions CheoMooRac/CheoMooRac/Sources/Views/MainTableViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}

0 comments on commit 6cb50aa

Please sign in to comment.