현상금 앱을 MVVM 패턴을 이용해서 재설정
Model, View, ViewModel로 구현
import UIKit
class BountyViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
// Model
// 이름, 정보 - BountyInfo
// View
// -ListCell에 필요한 정보를 ViewController가 아닌 ViewModel에게서 받아야함
// -ListCell은 ViewModel에게서 받은 정보를 View Update 하기
// ViewModel
// - BountyViewModel
// - View에서 필요한 메서드
// - Model -> BountyInfo 가지고 있기
let viewModel = BountyViewModel()
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// DetailViewController 데이터 줄꺼에요
if segue.identifier == "showDetail" {
let vc = segue.destination as? DetailViewController
if let index = sender as? Int {
let bountyInfo = viewModel.bountyInfo(at: index)
vc?.viewModel.update(model: bountyInfo)
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
}
// UITableViewDataSource
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return viewModel.numOfBountyInList
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as? ListCell else {
return UITableViewCell()
}
let bountyInfo = viewModel.bountyInfo(at: indexPath.row)
cell.update(info: bountyInfo)
return cell
}
// UITableViewDelegate
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("--> \(indexPath.row)")
performSegue(withIdentifier: "showDetail", sender: indexPath.row)
}
}
class ListCell: UITableViewCell {
@IBOutlet weak var imgView: UIImageView!
@IBOutlet weak var nameLabel: UILabel!
@IBOutlet weak var bountyLabel: UILabel!
func update(info: BountyInfo) {
imgView.image = info.image
nameLabel.text = info.name
bountyLabel.text = "\(info.bounty)"
}
}
struct BountyInfo {
let name: String
let bounty: Int
var image: UIImage? {
return UIImage(named: "\(name).jpg")
}
init(name: String, bounty: Int) {
self.name = name
self.bounty = bounty
}
}
class BountyViewModel {
let bountyInfoList: [BountyInfo] = [
BountyInfo(name: "brook", bounty: 33000000),
BountyInfo(name: "chopper", bounty: 50),
BountyInfo(name: "franky", bounty: 44000000),
BountyInfo(name: "luffy", bounty: 300000000),
BountyInfo(name: "nami", bounty: 16000000),
BountyInfo(name: "robin", bounty: 80000000),
BountyInfo(name: "sanji", bounty: 77000000),
BountyInfo(name: "zoro", bounty: 120000000)
]
var sortedList: [BountyInfo] {
let sortedList = bountyInfoList.sorted { (lhs, rhs) -> Bool in
return lhs.bounty > rhs.bounty
}
return sortedList
}
var numOfBountyInList: Int {
return bountyInfoList.count
}
func bountyInfo(at index: Int) -> BountyInfo {
return sortedList[index]
}
}
import UIKit
class DetailViewController: UIViewController {
// Model
// 이름,정보 BountyInfo
// View
// imgView, nameLabel, bountyLabel
// ViewModel를 통해서 정보를 받기
// ViewModel
// DetailViewModel
// view에 필요한 메서드
// Model, BountyInfo
@IBOutlet weak var imgView: UIImageView!
@IBOutlet weak var nameLabel: UILabel!
@IBOutlet weak var bountyLabel: UILabel!
let viewModel = DetailViewModel()
override func viewDidLoad() {
super.viewDidLoad()
updateUI()
}
func updateUI() {
if let bountyInfo = self.viewModel.bountyInfo {
imgView.image = bountyInfo.image
nameLabel.text = bountyInfo.name
bountyLabel.text = "\(bountyInfo.bounty)"
}
}
@IBAction func close(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
}
class DetailViewModel {
var bountyInfo: BountyInfo?
func update(model: BountyInfo?) {
bountyInfo = model
}
}