๐Ÿ“–Custom Delegate Pattern

๋ฉค๋ฒ„๋ผ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€/์ˆ˜์ •ํ•ด ํ…Œ์ด๋ธ” ๋ทฐ์— ํ‘œ์‹œํ•˜๋Š” ์•ฑ

DetailVC์—์„œ ๋ฉค๋ฒ„๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ๋ฉค๋ฒ„ ์ •๋ณด๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋ฉด VC์—์„œ ํ•ด๋‹น ์ •๋ณด๊ฐ€ ์—…๋ฐ์ดํŠธ๋˜๋„๋ก ๊ตฌํ˜„(VC : tableViewController)

๐Ÿ”–๋””์ž์ธ ํŒจํ„ด : MVC ํŒจํ„ด(View: Code ๊ตฌํ˜„)

๐Ÿ”–๋ฐ์ดํ„ฐ Member(name: name, age: age, phone: phone, address: address)

๐Ÿ”–๋ฐ์ดํ„ฐ์˜ ํ๋ฆ„ DetailVC (Sender) โ†’ VC (Receiver) DetailVC๊ฐ€ ์ผ์„ ์‹œํ‚ค๊ณ  VC๊ฐ€ ๋ฐ›์€ ์ผ์„ ๋Œ€์‹  ์ฒ˜๋ฆฌ

1. ๋ชจ๋ธ์— ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ ํ”„๋กœํ† ์ฝœ ๊ตฌํ˜„

protocol MemberDelegate: AnyObject {
ย  ย  func addNewMember(_ member: Member)
ย  ย  func update(index: Int, _ member: Member)
}
  • ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ๋ฅผ weak์œผ๋กœ ์„ ์–ธํ•  ๊ฒƒ์ด๋ฏ€๋กœ AnyObject ์ƒ์†

weak๊ณผ AnyObject

weak์€ ์˜ค์ง class์—์„œ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅ โ†’ class์—๋งŒ ์ฑ„ํƒํ•  ์ˆ˜ ์žˆ๋Š” ํ”„๋กœํ† ์ฝœ๋กœ ๋งŒ๋“ค์–ด์•ผ ํ•จ โ†’ AnyObject ์ƒ์†

๐Ÿ”–AnyObject ํด๋ž˜์Šค ํƒ€์ž… ์ธ์Šคํ„ด์Šค๋งŒ์„ ๋‚˜ํƒ€๋ƒ„

2. ์ผ์„ ์‹œํ‚ฌ ์ปจํŠธ๋กค๋Ÿฌ(Sender)์—์„œ ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ ํ”„๋กœํ† ์ฝœ ๋ณ€์ˆ˜ ์„ ์–ธ

class DetailViewController: UIViewController {
ย  ย  weak var delegate: MemberDelegate?
}
  • ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ๋Š” weak ( โˆต ๊ฐ•ํ•œ ์ˆœํ™˜ ์ฐธ์กฐ ๋ฐฉ์ง€)
  • ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ๋Š” ์˜ต์…”๋„ ( โˆต ์ผ์„ ์ง€์‹œํ•˜์ง€ ์•Š์„ ์ˆ˜๋„ ์žˆ์Œ)

3. ์ด๋ฒคํŠธ ๋ฐœ์ƒ ์‹œ Sender๋Š” ํ”„๋กœํ† ์ฝœ์— ์ •์˜ํ•ด ๋‘” ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์ผ์„ ์ง€์‹œ

๋ฒ„ํŠผ์ด ๋ˆŒ๋ฆฌ๋ฉด ์ž‘์—…์„ ์ง€์‹œ

Sender : ๋Œ€๋ฆฌ์ž์•ผ~~ ์ด๋ฒคํŠธ(๋ฉค๋ฒ„ ์ถ”๊ฐ€, ๋ฉค๋ฒ„ ์—…๋Žƒ) ๋ฐœ์ƒํ–ˆ์–ด~!! (Receiver๋Š” 5๋ฒˆ์— ๊ตฌํ˜„ํ•œ๋Œ€๋กœ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌํ•จ)

class DetailViewController: UIViewController {
ย  ย  func setupButtonAction() {
 
ย  ย  ย  ย  detailView.saveButton.addTarget(self, action: #selector(saveButtonTapped), for: .touchUpInside)
 
ย  ย  }
ย  ย  
ย  ย  @objc func saveButtonTapped() {
ย  ย  ย  ย  // MARK: ๋ฉค๋ฒ„๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ(์ƒˆ๋กœ์šด ๋ฉค๋ฒ„ ์ถ”๊ฐ€)
ย  ย  ย  ย  if member == nil {
ย  ย  ย  ย  ย  ย  let memberId = Int(detailView.idTextField.text!) ?? 0 // ๋ชจ๋ธ์— ์—…๋ฐ์ดํŠธ๋ฅผ ํ•  ๋•Œ, ๋ช‡ ๋ฒˆ ์งธ ๋ฉค๋ฒ„์ธ์ง€ ์•Œ์•„์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์–œ ๋ณ€์ˆ˜๋กœ ์„ค์ •
ย  ย  ย  ย  ย  ย  let name = detailView.nameTextField.text ?? ""
ย  ย  ย  ย  ย  ย  let age = Int(detailView.ageTextField.text ?? "")
ย  ย  ย  ย  ย  ย  let phone = detailView.phoneTextField.text ?? ""
ย  ย  ย  ย  ย  ย  let address = detailView.addressTextField.text ?? ""
 
ย  ย  ย  ย  ย  ย  var newMember = Member(name: name, age: age, phone: phone, address: address) // ๋‰ด ๋ฐ์ดํ„ฐ
ย  ย  ย  ย  ย  ย  
ย  ย  ย  ย  ย  ย  newMember.memberImage = detailView.mainImageView.image // ์ด๋ฏธ์ง€๋ทฐ์— ์žˆ๋Š” ๊ฒƒ์„ ๊ทธ๋Œ€๋กœ ๋‹ค์‹œ ๋ฉค๋ฒ„์— ์ €์žฅ
ย  ย  ย  ย  ย  ย  
ย  ย  ย  ย  ย  ย  delegate?.addNewMember(newMember)
ย  ย  ย  ย  ย  ย  //  MARK: ๋ฉค๋ฒ„๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ(๊ธฐ์กด ๋ฉค๋ฒ„์˜ ๋‚ด์šฉ์„ ์—…๋ฐ์ดํŠธ)
ย  ย  ย  ย  } else {
ย  ย  ย  ย  ย  ย  // ์ด๋ฏธ์ง€๋ทฐ์— ์žˆ๋Š” ๊ฒƒ์„ ๊ทธ๋Œ€๋กœ ๋‹ค์‹œ ๋ฉค๋ฒ„์— ์ €์žฅ
ย  ย  ย  ย  ย  ย  member!.memberImage = detailView.mainImageView.image
 
ย  ย  ย  ย  ย  ย  let memberId = Int(detailView.idTextField.text!) ?? 0 // ๋ชจ๋ธ์— ์—…๋ฐ์ดํŠธ๋ฅผ ํ•  ๋•Œ, ๋ช‡ ๋ฒˆ ์งธ ๋ฉค๋ฒ„์ธ์ง€ ์•Œ์•„์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์–œ ๋ณ€์ˆ˜๋กœ ์„ค์ •
ย  ย  ย  ย  ย  ย  member!.name = detailView.nameTextField.text ?? ""
ย  ย  ย  ย  ย  ย  member!.age = Int(detailView.ageTextField.text ?? "") ?? 0
ย  ย  ย  ย  ย  ย  member!.phone = detailView.phoneTextField.text ?? ""
ย  ย  ย  ย  ย  ย  member!.address = detailView.addressTextField.text ?? ""
ย  ย  ย  ย  ย  ย  
ย  ย  ย  ย  ย  ย  // ๋ทฐ์—๋„ ๋ฐ”๋€ ๋ฉค๋ฒ„๋ฅผ ์ „๋‹ฌํ•ด ๋ฐ˜์˜ (๋ทฐ์ปจํŠธ๋กค๋Ÿฌ ==> ๋ทฐ)
ย  ย  ย  ย  ย  ย  detailView.member = member
ย  ย  ย  ย  ย  ย  
ย  ย  ย  ย  ย  ย  delegate?.update(index: memberId, member!)
ย  ย  ย  ย  }
ย  ย  }
}

4. ์ผ์„ ํ•  ์ปจํŠธ๋กค๋Ÿฌ(Receiver)๋Š” ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ๋ฅผ ์ฑ„ํƒ

DetailVC (Sender) ๋Œ€์‹  ์ผ์„ ํ•˜๊ธฐ ์œ„ํ•ด VC (Receiver)๋Š” DetailVC (Sender)์—๊ฒŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๊ณณ(ํ™”๋ฉด์ „ํ™˜์ด ์ผ์–ด๋‚˜๋Š” ๊ณณ)์—์„œ DetailVC (Sender)์— ์ ‘๊ทผํ•ด ๋ณธ์ธ์„ ๋Œ€๋ฆฌ์ž๋กœ ์„ค์ •

ํ…Œ์ด๋ธ”๋ทฐ์—์„œ add ๋ฒ„ํŠผ์„ ํ†ตํ•œ ํ™”๋ฉด ์ „ํ™˜(๋ฉค๋ฒ„ ์ถ”๊ฐ€)

final class ViewController: UIViewController {
ย  ย  lazy var plusButton: UIBarButtonItem = {
ย  ย  ย  ย  let button = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(plusButtonTapped))
 
ย  ย  ย  ย  return button
ย  ย  }()
ย  ย  
ย  ย  @objc func plusButtonTapped() {
ย  ย  ย  ย  let detailVC = DetailViewController()
 
ย  ย  ย  ย  detailVC.delegate = self
 
ย  ย  ย  ย  navigationController?.pushViewController(detailVC, animated: true)
ย  ย  }
}

cell ํ„ฐ์น˜๋ฅผ ํ†ตํ•œ ํ™”๋ฉด์ „ํ™˜(๋ฉค๋ฒ„ ์ •๋ณด ์—…๋ฐ์ดํŠธ)

extension ViewController: UITableViewDelegate {
ย  ย  func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
ย  ย  ย  ย  let detailVC = DetailViewController()
ย  ย  ย  ย  detailVC.delegate = self
 
ย  ย  ย  ย  let array = memberListManager.getMemberList()
ย  ย  ย  ย  detailVC.member = array[indexPath.row]
ย  ย  ย  ย  
ย  ย  ย  ย  navigationController?.pushViewController(detailVC, animated: true)
ย  ย  }
}
  • Receiver(๋Œ€๋ฆฌ์ž) : ๋‚ด๊ฐ€ Sender์˜ ๋Œ€๋ฆฌ์ž๊ฐ€ ๋˜๊ฒ ๋‹ค!!!(๋‚ด๊ฐ€ Sender ๋Œ€์‹  ์ผ์„ ์ฒ˜๋ฆฌํ• ๊ฒŒ!!)

5. Receiver(๋Œ€๋ฆฌ์ž)๋Š” ์ง€์‹œ๋ฐ›์€ ๋™์ž‘์„ Sender ๋Œ€์‹  ์ฒ˜๋ฆฌ

๋ฐ์ดํ„ฐ ์ถ”๊ฐ€/์—…๋ฐ์ดํŠธ ํ›„ ํ™”๋ฉด ๋ฆฌ๋กœ๋“œ

Receiver : ๋‚œ ๋ฉค๋ฒ„ ์ถ”๊ฐ€ ๋์„ ๋•Œ ์ด๋ ‡๊ฒŒ ์ฒ˜๋ฆฌํ• ๊ฑฐ์•ผ ๋ฉค๋ฒ„ ์ •๋ณด๊ฐ€ ์—…๋ฐ์ดํŠธ๋์„ ๋• ์š”๋ ‡๊ฒŒ ์ฒ˜๋ฆฌํ• ๊ฑฐ์•ผ

extension ViewController: MemberDelegate {
ย  ย  func addNewMember(_ member: Member) {
ย  ย  ย  ย  memberListManager.makeNewMember(member)
ย  ย  ย  ย  tableView.reloadData()
ย  ย  }
 
ย  ย  func update(index: Int, _ member: Member) {
ย  ย  ย  ย  memberListManager.updateMemberInfo(index: index, member)
ย  ย  ย  ย  tableView.reloadData()
ย  ย  }
}
  • ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ ํ”„๋กœํ† ์ฝœ ๋ฉ”์„œ๋“œ๋ฅผ ์ •์˜
  • ์ด ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด Sender์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌ๋ฐ›๊ณ  ๋Œ€์‹  ์ž‘์—… ์ˆ˜ํ–‰