반응형
이번에 만든
바둑선수는 항상 바둑을 둔 다음 복기를 하는 과정을 갖는다.
회고 : 스스로에 대한 배움을 하는 것이고 그것을 통해 성장하는 것
실무에서는 동료들과 코드리뷰라는 과정을 통해 회고를 한다.
왜 이렇게 작성했는지, 이렇게 작성할 경우 실무에서 문제가 생기지는 않을지
지속적으로 코드리뷰를 하다보면 그전에 자가리뷰를 하게 된다.
더보기
BountyViewController
//
// BountyViewController.swift
// BountyList
//
// Created by hyeonseok on 2021/10/27.
//
import UIKit
class BountyViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
let nameList = ["brook", "chopper", "franky", "luffy", "nami", "robin", "sanji", "zoro"]
let bountyList = [33000000, 50, 44000000, 300000000, 16000000, 80000000, 77000000, 120000000]
//세그웨이를 준비하는 함수 ; UIViewController에 이미 구현되어있는데 상속을 했기때문에 override해야함
//이때 세그웨이를 사용하면서 필요한 데이터를 알려줘야한다.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// DetailViewController 에게 데이터를 준다.
// UITableViewDelegate의 sender로 부터 몇번째 셀인지 받았고 Any?로 받았기 때문에 index를 int로 다운캐스팅
if segue.identifier == "showDetail"{
let vc = segue.destination as? DetailViewController
if let index = sender as? Int {
vc?.name = nameList[index]
vc?.bounty = bountyList[index]
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
// UITableViewDataSource
// //몇개가 필요하니??
// func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// return 2
// }
//
// //어떻게 표현할거니?
// func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//
// let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
// //cell = identifier for -> 셀의 위치
// return cell
//
//}
//
// //UITableViewDelegate
// //어떻게 반응할거야??
// func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// print("--> \(indexPath.row)")
// }
//몇개가 필요하니??
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return bountyList.count
}
//어떻게 표현할거니?
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// --> 첫번째 방법
guard let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as? ListCell else {
return UITableViewCell()
}
let img = UIImage(named: "\(nameList[indexPath.row]).jpg")
cell.imgView.image = img
cell.nameLabel.text = nameList[indexPath.row]
cell.bountyLabel.text = "\(bountyList[indexPath.row])"
return cell
}
//
//// --> 두번째 방법
// if let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as? ListCell {
// let img = UIImage(named: "\(nameList[indexPath.row]).jpg")
// cell.imgView.image = img
// cell.nameLabel.text = nameList[indexPath.row]
// cell.bountyLabel.text = "\(bountyList[indexPath.row])"
// return cell
// } else {
// return UITableViewCell()
// }
// }
// UITableViewDelegate
// 어떻게 줄거니
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("--> \(indexPath.row)")
//연결한 segue웨이를 수행하라는 코드 여러개의 세그웨이가 있을수 있어서 구분자 showDetail사용
//sender가 prepare함수를 사용할 때 몇번째 셀인지 알려주는 역할을 수행
performSegue(withIdentifier: "showDetail", sender: indexPath.row)
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
}
class ListCell: UITableViewCell {
@IBOutlet weak var imgView: UIImageView!
@IBOutlet weak var nameLabel: UILabel!
@IBOutlet weak var bountyLabel: UILabel!
}
DetailViewController
//
// DetailViewController.swift
// BountyList
//
// Created by hyeonseok on 2021/10/28.
//
import UIKit
class DetailViewController: UIViewController {
@IBOutlet weak var imgView: UIImageView!
@IBOutlet weak var nameLabel: UILabel!
@IBOutlet weak var bountyLabel: UILabel!
//BountyView로부터 받아올 변수 지정 (옵셔널)
var name: String?
var bounty: Int?
//ViewController가 뜨기 직전, 메모리에 올라왔을 때 ViewDidLoad가 실행된다. 이때 updateUI가 실행됨
override func viewDidLoad() {
super.viewDidLoad()
updateUI()
}
//UI컴포넌트들을 업데이트 하는 메서드. 옵셔널바인딩을 사용
func updateUI() {
if let name = self.name, let bounty = self.bounty {
let img = UIImage(named: "\(name).jpg")
imgView.image = img
nameLabel.text = name
bountyLabel.text = "\(bounty)"
}
}
@IBAction func close(_ sender: Any) {
//dismiss 사라지고나서 후에 동작해야할 것들을 적어줌
dismiss(animated: true, completion: nil)
}
}
1. 앱을 보면 현상금이 나와있는데 랭킹앱이긴 하지만 랭킹을 보긴 어렵다. -> 정렬도 되어있지 않다.
let nameList = ["brook", "chopper", "franky", "luffy", "nami", "robin", "sanji", "zoro"]
let bountyList = [33000000, 50, 44000000, 300000000, 16000000, 80000000, 77000000, 120000000]
이름과 순서를 변경하려면 매우 복잡한 과정이 생긴다. 일일히 매칭하는 것을 찾는 것도 굉장히 번거로울 뿐만아니라
실무로 봤을 때, 에러가 생길 수 있는 것이다.
가장큰 문제는 이름과 현상금이 연결되어있지 않다는 것이다. -> 데이터가 묶여있지않기때문에 각각 접근했다.
결과적으로 봤을 때, 코드는 짰지만 고치기가 어렵고 재사용하기 어렵다는 것
기술부채 : 고쳐야 하는데 아직 고치지 못한것 -> 아예 없을 수는 없지만 엔지니어들은 이것을 최소화해야한다.
기술부채가 쌓이지 않게 하기위한 개발자들의 전략들이 있다. -> 디자인패턴
다음에 공부할 것은 MVVM패턴이다.
반응형
'모바일앱 > iOS' 카테고리의 다른 글
구조체와 클래스 복습 (0) | 2021.11.16 |
---|---|
투두리스트앱 만들기(진행중) (0) | 2021.11.12 |
투두리스트앱 만들기(구현계획) (0) | 2021.11.11 |
원피스 랭킹 앱 프로젝트 Review (BountyListApp) (0) | 2021.11.10 |
원피스 현상금 랭킹앱 만들기(6) - 뷰컨트롤러 간 데이터 전달하기 (0) | 2021.11.08 |
원피스 현상금 랭킹앱 만들기(5) - 디테일뷰 모달로 띄우기 (0) | 2021.11.04 |
원피스 현상금 랭킹앱 만들기(4) - 커스텀셀 (0) | 2021.11.03 |
원피스 현상금 랭킹앱 만들기(3) - 테이블뷰 프로토콜 (0) | 2021.10.31 |