개인적으로 정리한 내용을 기록한 글입니다. 티스토리 블로그의 글을 마크다운 형식으로 재작성하였습니다.

Delegate Pattern은 다른 곳에 실제로 구현할 내용을 맡겨 놓고 규격만 정해 전달하는 패턴을 의미한다. 규격은 protocol을 이용해 정의할 수 있는데, 이는 자바의 인터페이스와 유사하다고 볼 수 있다.

다음과 같이 스토리보드를 구성한다고 할 때,



스토리보드 구성 Button을 통해 이동한 두번째 뷰의 텍스트 필드에 입력한 내용이 첫번째 뷰의 레이블에 나타나도록 구현하고자 한다. 이렇게 여러 뷰가 있을 때 하나의 뷰에서 다른 뷰로 데이터 전달이 필요할 때 사용자가 직접 델리게이트를 정의하여 그 기능을 구현할 수 있다.

우선, 입력된 데이터를 불러오기 위한 메서드가 포함된 델리게이트를 정의한다.

protocol InputData {
    func load(_ text: String)
}


두번째로, 델리게이트 변수를 뷰 컨트롤러 클래스에 선언한다. 델리게이트 변수를 선언함으로써 내부 메서드를 사용할 수 있게 된다.

class InputViewController: UIViewController {
    var delegate: InputData? // 델리게이트 변수 생성
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}


텍스트 필드의 내용이 변할 때마다 델리게이트 메서드를 호출하기 위해 IBAction 메서드를 작성한다.

@IBAction func textChanged(_ sender: UITextField) {
    delegate?.load(sender.text ?? "")
}


이렇게만 해놓으면 텍스트필드의 내용이 전달되어 레이블에 나타날 것 같지만, 그렇지 않다. 델리게이트를 정의만 해놓았을 뿐, 메서드에 대한 구현을 하지 않았기 때문이다. 또한, 레이블의 텍스트를 바꾸려면 UILabel 변수의 text 프로퍼티 값을 변경해야하는데, 지금까지의 코드 작성에서는 그러한 내용이 하나도 들어가 있지 않았다.

정리해보자면,

첫번째 뷰와 델리게이트의 연결
델리게이트 메서드 구현
첫번째 뷰의 레이블 변수 설정

위와 같은 작업이 추가로 더 필요하다.

첫번째 뷰와 델리게이트의 연결을 위해 prepare 메서드를 override 한 후 내용을 작성한다.

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    if segue.identifier == "inputSeg" {
    
        let inputVC = segue.destination as! InputViewController
        inputVC.delegate = self
        
    }
}

세그웨이의 목적지를 두번째 뷰 컨트롤러인 InputViewController로 타입캐스팅 후 delegate 프로퍼티를 첫번째 뷰 컨트롤러인 self로 지정한다.

이후, 첫번째 뷰가 델리게이트를 상속 받도록 하고 델리게이트 메서드를 구현한다.

class ViewController: UIViewController, InputData {   
    @IBOutlet var lblId: UILabel!
    func load(_ text: String) {
        lblId.text = text
    }
	// ...중략
}



실행 결과는 다음과 같다.




참고: https://www.inflearn.com/course/ios