article thumbnail image
Published 2022. 10. 7. 17:22

Delegate란, 한국말로 위임이란 뜻이며, 

object가 해야되는 행위 다른 object로 위임(대신)하는 pattern 이다.

iOS에서 delegate는 protocol로 구현이 된다. 

우선, 이 protocol에 대해 간단히 살펴 보자 

 

Protocol 

protocol은 정의를 하고 제시를 할 뿐 기능을 구현하지는 않는 하나의 타입이다.

struct나, class는 이를 상속하는 것이 아닌 채택한다는 표현을 쓴다.

 

쉽게 말하자면, Protocol은 하나의 행동 규범 혹은 이라고 생각하면 된다. 

 

음식점을 가지고 예시를 들어보자!

기본적으로 음식점을 차리기 위해선 요리를 해야한다.

또한, 음식도 팔아야 한다

 

즉, 

음식점을 protocol로 생각하자면, 

요리를한다, 음식을 판다 ... 등등의 함수들은

는 음식점이 되기 위한 기본틀이다.

 

각각의 음식점마다 요리를 하는 레시피, 음식을 파는 방식이 다르므로 "요리를한다", "음식을판다" 

내부는 각각의 음식점에서 구현하면 되는 것이다. 

 

 

 

 

Delegate Pattern

delegate pattern을 사용하기 위해선 아래의 내용들이 필요하다 

 

A 를 위임할 객체, B를 위임받은 객체라고 한다면,

  • Protocol : B가 A에게 전달할 message의 규칙(약속)
  • Receiver(A) : B가 특정 기능들을 수행하고 전달받을 대상
  • Delegate(B) : A를 대신하여 처리할 B 

 

즉, A는 B에게 protocol에 있는 규칙(약속)들을 위임하는 것이다!

 

실제 우리는 tableView를 사용할때, viewcontroller에서 

아래와 같이 사용하는 것을 자주 볼수 있다.

class ViewController: UIViewController, UITableViewDelegate {
    
    @IBOutlet weak var myTableView: UITableView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        myTableView.delegate = self
    }
}

이는 UITableViewDelegate는 protocol이고, 실제로 

이렇게 여러가지 함수들이 있다. 

 

또한 UITableView의 property중에는 

    weak open var delegate: UITableViewDelegate?

 

 

 

대리자를 위임할 수 있는 property가 있다. 

이를 이용해서 

myTableView.delegate = self 

 

 

myTableView의 대리자를 ViewController로 선언 

할 수 있다.

 

 

즉,

protocol : UITableViewDelegate

Reciever : myTableView

Delegate : ViewController 

다음과 같은 관계가 되는 것이다.

 

 

 

Custom Delegate Pattern

왼쪽의 viewController는 LabelViewController,

오른쪽의 viewController는 EditingViewController이다.

LabelViewController에서 "start Editing" 버튼을 누르게 되면 

EiditingViewController로 이동하게 된다. 

 

EditingViewController의 textField에서 입력을 하고 "Finish Editing"버튼을 누르게 되면

LabelViewController의 LabelEditingViewController에서 입력하였던 text가 표시 되게 해보자!

 

 

다음은, finishEditing 버튼이 눌렀을때의 action이다. 

@IBAction func finishEditingPressed(_ sender: UIButton) {
    self.dismiss(animated: true)
    //textField의 text를 LabelViewController로 전달
}

해당 action에 textField의 text를 전달하기 위해서 이제 custom delegate를 적용해보자! 

 

기초적인 설계부터 하면 

Receiver : EditingViewController

Delegate : LabelViewController

Protocol : textField의 text를 LabelViewController의 label에 표시

 

즉! EiditingViewControllertextField의 textLabelViewController에 전달하고!

Delegate(대리자)LabelViewController받은 text로 label에 표시한다.

 

이를 바탕으로 protocol을 설계해보자!

protocol MyDelegate: AnyObject {
    func didEditingText(_ text: String)
}

 

다음으로,  EditingViewController는 에서는 

weak var delegate: MyDelegate?

위와 같은 Property를 만들어주고! 

@IBAction func finishEditingPressed(_ sender: UIButton) {
    self.dismiss(animated: true)
    
    if let text = textField.text {
        delegate?.didEditingText(text)

    }
}

textField.text는 Optional이므로 Optional binding을 해준뒤! 

text를 delegate로 전달하면서, didEditingText의 동작을 delegate로 위임한다.

 

다음, LabelViewController에서,

@IBAction func startEditingPressed(_ sender: UIButton) {
    let vc = storyboard?.instantiateViewController(withIdentifier: "EiditingViewController") as! EiditingViewController
    vc.modalPresentationStyle = .fullScreen
    
    vc.delegate = self //delegate
    present(vc, animated: true)
}

 EiditingViewController의 delegate(대리자)를 자기 자신으로 지정한다.

 

마지막으로, 

extension LabelViewController: MyDelegate {
    func didEditingText(_ text: String) {
        label.text = text
    }
}

protocol을 채택하여 didEiditingText의 구현을 delegate (LabelViewController)에서 한다.

'iOS > Swift' 카테고리의 다른 글

[Swift] KVO, Delegate and Notification  (2) 2022.10.08
[Swift] Notification  (0) 2022.10.08
[Swift] KVO (Key-Value-Observing)  (0) 2022.10.06
[Swift] KVC (Key-Value-Coding)  (1) 2022.10.05
[Swift] Subscript  (4) 2022.10.05
복사했습니다!