Skip to content

Latest commit

ย 

History

History
270 lines (209 loc) ยท 10.2 KB

README.md

File metadata and controls

270 lines (209 loc) ยท 10.2 KB

๐Ÿฅ we are EARLY-BUDDY-iOS

์–ผ๋ฆฌ๋ฒ„๋”” - ์•ฝ์†์‹œ๊ฐ„์„ ์œ„ํ•œ ๋‚˜๋งŒ์˜ ๋Œ€์ค‘๊ตํ†ต ๋ฐฐ์ฐจ ์•Œ๋ฆฌ๋ฏธ

SOPT 25๊ธฐ Appjam '์–ผ๋ฆฌ๋ฒ„๋””'

ํ”„๋กœ์ ํŠธ ๊ธฐ๊ฐ„ 2019.12 ~ ์ง„ํ–‰์ค‘


Work-Flow

workflow


๊ฐœ๋ฐœํ™˜๊ฒฝ

โœ”๏ธ 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)
    }

๐Ÿ†˜ ํ†ต์‹  ์‹œ ์ ‘๊ทผ์‹œ๊ฐ„ ์ดˆ๊ณผ์˜ ์ด์Šˆ๊ฐ€ ์žˆ์—ˆ์Œ โœ”๏ธ ๋Œ€์ค‘์ ์ธ ์ด์Šˆ์ง€๋งŒ, ์•„์ง ํ•ด๊ฒฐ๋ฒ•์„ ์ฐพ์ง€ ๋ชปํ•จ


์–ผ๋ฆฌ๋ฒ„๋”” iOS ๊ฐœ๋ฐœ์ž

๐Ÿ‘ฉ๐Ÿปโ€๐Ÿ’ป ๋ฆฌ๋“œ - ๊น€ํ˜„์ง€
๐Ÿ‘ฉ๐Ÿปโ€๐Ÿ’ป ํ™ฉํšจ์ง„
๐Ÿ‘ฉ๐Ÿปโ€๐Ÿ’ป (์„œํฌํŠธ) ๋ฐ•๊ฒฝ์„