SOPT 25๊ธฐ Appjam '์ผ๋ฆฌ๋ฒ๋'
ํ๋ก์ ํธ ๊ธฐ๊ฐ 2019.12 ~ ์งํ์ค
โ๏ธ Swift 5
โ๏ธ Xcode 11.3
โ๏ธ Alamofire
โ๏ธ Hero
โ๏ธ Snapkit
๐ง ํํ๋ฉด ๐ง
๐ง ์ผ์ ๋ฑ๋ก ๐ง
๊ธฐ๋ฅ | ์ฐ์ ์์ | ๊ฐ๋ฐ์ฌ๋ถ | ๋ด๋น |
---|---|---|---|
ํธ์์๋ | 1์์ | ๊ฐ๋ฐ์ ๊ณ์ ์์ด ์งํ ๋ถ๊ฐ | - |
ํ | 1์์ | ๋ทฐ ์์ฑ ํต์ ์งํ์ค |
ํ์ง |
์ผ์ ๋ฑ๋ก | 1์์ | ๋ทฐ ์์ฑ ํต์ ์งํ์ค |
ํ์ง |
์ฃผ์ ๊ฒ์ | 1์์ | ๋ทฐ ์์ฑ ํต์ ์์ฑ |
ํ์ง |
๊ฒฝ๋ก ๋ณด์ฌ์ฃผ๊ธฐ | 1์์ | ๋ทฐ ์์ฑ ํต์ ์งํ์ค |
ํ์ง |
์ ๊ฑฐ์ฅ ์์น | 1์์ | ๋ทฐ ์งํ์ค | ํ์ง |
์ผ์ ์์ธ๋ณด๊ธฐ | 1์์ | ๋ทฐ ์์ฑ ํต์ ์งํ์ค |
ํ์ง |
์ต์ด์ฌ์ฉ | 2์์ | ๋ทฐ ์์ฑ ํต์ ์งํ์ค |
๊ฒฝ์ |
๋ก๊ทธ์ธ / ํ์๊ฐ์ | 2์์ | ๋ทฐ ์์ฑ ํต์ ์์ฑ |
๊ฒฝ์ |
์บ๋ฆฐ๋ | 2์์ | ๋ทฐ ์์ฑ ํต์ ์งํ์ค |
๋ทฐ,๊ธฐ๋ฅ - ํ์ง ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์์ - ํจ์ง |
๋ง์ดํ์ด์ง | 3์์ | ๋ทฐ ์์ฑ ํต์ ์งํ์ค |
ํ์ง |
๐ ๊ฒฝ๋ก ๋ทฐ๋ฅผ ๋์ ์ผ๋ก ์์ง์ด๋ ๊ฒ์ ์ด๋ ค์์ ๊ฒช์
โ๏ธ ํ ์ด๋ธ ๋ทฐ ์์ ์ปฌ๋ ์ ๋ทฐ ๋ฃ์ด์ ์ ์ width๋ฅผ ๋์ ์ผ๋ก ๊ทธ๋ฆผ
โ๏ธ ํ ์ด๋ธ ๋ทฐ์์ expandable ํจ๊ณผ๋ฅผ ์ ์ฉํด ๊ฒฝ๋ก๋ฅผ ๊ทธ๋ฆผ
// ๋ทฐ์ ๋ํ๋๋ ๊ฒฝ๋ก ๊ณ์ฐ
func timeRate(dummySet: [Route]) -> [Double] {
// view width 318
var ratio = [Double]()
dummySet.forEach {
if $0.type != .none {
ratio.append(Double(318/90) * Double($0.min!))
} else {
ratio.append(10.0)
}
}
print("*****\(ratio)")
return ratio
}
// ํ
์ด๋ธ ๋ทฐ ํ๋กํ ์ฝ ์ ์ (๋๋ฏธ๋ฐ์ดํฐ)
extension SelectPathViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "PathCell", for: indexPath) as! PathCell
let path = paths[indexPath.row]
cell.totalTimeLabel.text = path.totalTimeLabel
cell.totalTransport.text = path.totalTransport
cell.transferCount.text = path.transferCount
cell.totalWalkTime.text = path.totalWalkTime
cell.totalCost.text = path.totalCost
cell.testSet = testSet
cell.ratio = timeRate(dummySet: testSet)
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 150
}
}
๐ ๋ค๋น๊ฒ์ด์ ๋ฐ๋ฅผ ์ปค์คํ ํ๊ณ , ๋ค๋ฅธ ์คํ ๋ฆฌ๋ณด๋๋ก ๋ค๋น๊ฒ์ด์ ์ฐ๊ฒฐํ๋ ๊ฒ์ ์ด๋ ค์์ ๊ฒช์
โ๏ธ ๋ค๋ฅธ ์คํ ๋ฆฌ๋ณด๋๋ก ์ฐ๊ฒฐํ ๋ pushViewController๋ฅผ ์ฌ์ฉํด์ ์ฐ๊ฒฐํ๊ณ , ์ฝ๋๋ก ๋ค๋น๊ฒ์ด์ ๋ฐ๋ฅผ ์ปค์คํ
override func viewWillAppear(_ animated: Bool) {
...
addImageButton.addTarget(self, action: #selector(goToMine), for: .touchUpInside)
...
}
// ๋ค๋ฅธ ์คํ ๋ฆฌ๋ณด๋๋ก ํ๋ฉด ์ ํ
@objc func goToMine() {
guard let nextVC = UIStoryboard(name: "Schedule", bundle: nil).instantiateViewController(withIdentifier: "MainScheduleViewController") as? MainScheduleViewController else { return }
nextVC.modalPresentationStyle = .fullScreen
self.navigationController?.pushViewController(nextVC, animated: true)
}
// ๋ค๋น๊ฒ์ด์
๋ฐ ์ปค์คํ
ํจ์
func customNavigationBar() {
self.view.layer.backgroundColor = UIColor.white.cgColor
self.navigationController?.setNavigationBarHidden(false, animated: true)
self.title = "์ฅ์ ์ ํ"
self.navigationController?.navigationBar.titleTextAttributes = [.foregroundColor: UIColor.white, .font: UIFont(name: "NotoSansKR-Medium", size: 18)!, .kern: CGFloat(-0.9)]
self.navigationController?.navigationBar.barTintColor = UIColor.mainblue
self.navigationController?.navigationBar.shadowImage = UIImage()
self.navigationController?.navigationBar.isTranslucent = false
self.navigationController?.navigationBar.backIndicatorImage = UIImage(named: "ic_back")
self.navigationController?.navigationBar.backIndicatorTransitionMaskImage = UIImage(named: "ic_back")
self.navigationController?.navigationBar.topItem?.title = ""
self.navigationController?.navigationBar.tintColor = UIColor.white
}
๐ dismiss๋๋ ํ์ ๋ทฐ์์ ๊ธฐ์กด ๋ทฐ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ ๊ฒ์ ์ด๋ ค์์ ๊ฒช์
โ๏ธ ํ๋กํ ์ฝ์ ์ ์ํด Delegate Pattern ์ ์ฉ
// dismiss๋๋ ๋ทฐ ์ปจํธ๋กค๋ฌ
protocol SendDataDelegate {
func sendData(data: String)
}
class PreferPopUpViewController: UIViewController {
var delegate: SendDataDelegate?
@IBAction func confirmAction(_ sender: UIButton) {
if !allCheckImg.isHidden {
if let data = allLabel.titleLabel?.text {
delegate?.sendData(data: data)
dismiss(animated: true, completion: nil)
}
} else if !busCheckImg.isHidden {
if let data = busLabel.titleLabel?.text {
delegate?.sendData(data: data)
dismiss(animated: true, completion: nil)
}
} else {
if let data = subwayLabel.titleLabel?.text {
delegate?.sendData(data: data)
dismiss(animated: true, completion: nil)
}
}
}
}
// ๊ฐ์ ์ ๋ฌ๋ฐ๋ ๋ทฐ ์ปจํธ๋กค๋ฌ
class SelectPathViewController: UIViewController, SendDataDelegate {
// delegate ํจ์ ์ ์
func sendData(data: String) {
preferLabel.text = data
}
๐ ํ์ ์ฐฝ์์ ๋ฒํผ์ ํด๋ฆญํ๋ฉด ํ์ผ๋ก ๋ค๋น๊ฒ์ด์ pop ๋์ด์ผํ๋ ํจ๊ณผ๊ฐ ์์๋๋ฐ, ํ์ ๋ทฐ์๋ navigation controller๊ฐ ์ฐ๊ฒฐ๋์ด์์ง ์์ pop์ด ์ ์ฉ๋์ง ์์์
โ๏ธ onFinished(), onComplete() ํจ์๋ฅผ ์ ์ฉํด ํด๊ฒฐ
// ํ์
๋ทฐ ์ปจํธ๋กค๋ฌ
class PopUpViewController: UIViewController {
var onFinished: (() -> Void)?
var onComplete: (() -> Void)?
override func viewDidLoad() {
super.viewDidLoad()
self.homeButton.addTarget(self, action: #selector(goToHome), for: .touchUpInside)
self.checkButton.addTarget(self, action: #selector(goToDetail), for: .touchUpInside)
}
@objc func goToHome() {
self.confirm = false
self.dismiss(animated: true)
onFinished?()
}
@objc func goToDetail() {
self.confirm = true
print("goToDetail \(confirm)")
self.dismiss(animated: true)
onComplete?()
}
}
// ํ์
๋ทฐ๋ฅผ ๋์ฐ๋ ๋ทฐ ์ปจํธ๋กค๋ฌ
@IBAction func showConfirmAction(_ sender: UIButton) {
let storyboard = UIStoryboard(name: "Schedule", bundle: nil)
let myAlert = storyboard.instantiateViewController(withIdentifier: "PopUpViewController") as! PopUpViewController
myAlert.modalPresentationStyle = UIModalPresentationStyle.overCurrentContext
myAlert.modalTransitionStyle = UIModalTransitionStyle.crossDissolve
guard let nextVC = UIStoryboard(name: "Schedule", bundle: nil).instantiateViewController(identifier: "DetailScheduleViewController") as? DetailScheduleViewController else { return }
nextVC.modalPresentationStyle = .fullScreen
myAlert.onFinished = { [weak self] in
self?.navigationController?.popViewController(animated: true)
}
myAlert.onComplete = { [weak self] in
self?.navigationController?.pushViewController(nextVC, animated: true)
}
self.present(myAlert, animated: true, completion: nil)
}
๐ ํต์ ์ ์ ๊ทผ์๊ฐ ์ด๊ณผ์ ์ด์๊ฐ ์์์ โ๏ธ ๋์ค์ ์ธ ์ด์์ง๋ง, ์์ง ํด๊ฒฐ๋ฒ์ ์ฐพ์ง ๋ชปํจ
๐ฉ๐ปโ๐ป ๋ฆฌ๋ - ๊นํ์ง
๐ฉ๐ปโ๐ป ํฉํจ์ง
๐ฉ๐ปโ๐ป (์ํฌํธ) ๋ฐ๊ฒฝ์