Things take time

[SWIFT] 딜리게이트(Delegate) 패턴 사용하기 본문

iOS (기능)

[SWIFT] 딜리게이트(Delegate) 패턴 사용하기

겸손할 겸 2019. 1. 2. 10:43

[딜리게이트]


delegate는 기본적으로 특정 프로토콜을 상속받아 해당 프로토콜에서 선언된 함수들을 override하여 사용한다.

간단한 테이블 뷰, 컬렉션 뷰 부터 시작해서 앨범 접근이나 여러 상황에서 많이 사용되는데(UI 컴포넌트에 의한 프로토콜), 이 것을 바탕으로 내가 작성한 클래스 파일을 다른 클래스 파일에서 프로토콜을 상속받아 사용할 수 있도록 하겠다.


안드로이드의 대응 단어로는 startAtivityForResult로 해서 해당 액티비티를 열고, 받아와서 onActivityResult에서 처리하는 경우와 비슷한 것으로 볼 수 있겠다.



[준비물, 로직]


2개의 뷰 컨트롤러 (ProcViewController, DeleViewController)


앱이 열리고 초기 뷰 컨트롤러는 DeleViewController이다. DeleViewController에서 버튼을 누르면 ProcViewController를 호출하는데, 이 때 ProcViewController에 선언된 프로토콜을 상속받아 delegate 선언을 해준다. ProcViewController가 열리고 ProcViewController안에 있는 버튼을 누르면 dismiss를 하되, 프로토콜안에 있는 딜리게이트 함수를 호출하고 종료한다.


[코드]


1. ProcViewController.swift

import UIKit

protocol ProcViewDelegate: class {
    func didBtnClicked(data: String)
}

class ProcViewController: UIViewController {
    var procViewDelegate: ProcViewDelegate?

    @IBOutlet weak var btnTest: UIButton!
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    @IBAction func btnClicked(_ sender: UIButton) {
        procViewDelegate?.didBtnClicked(data: "data send")
        self.dismiss(animated: true)
    }
}

프로토콜을 하나 선언해주고, 프로토콜 내에 함수를 하나 선언한다. 자바의 인터페이스와 비슷한 개념이랄까.

이 프로토콜을 상속받는 다른 클래스는, 프로토콜 내에 선언된 함수를 구현해야한다. 물론 여기에 optional도 사용 가능하다. optional로 선언된 함수는 상속받는 클래스에서 구현하지 않아도 된다. 이때는 인터페이스보단 추상 클래스랑 비슷한 개념.


간단한 사용방법은 프로토콜 부분을 아래처럼

@objc protocol ProcViewDelegate: class {
    func didBtnClicked(data: String)
    @objc optional func thisIsOptionFunc()
}


2. DeleViewController.swift (init view controller)

import UIKit class DeleViewController: UIViewController, ProcViewDelegate { func didBtnClicked(data: String) { self.deleBtn.setTitle(data, for: .normal) } @IBOutlet weak var deleBtn: UIButton! override func viewDidLoad() { super.viewDidLoad() } @IBAction func deleBtnClicked(_ sender: UIButton) { if let procVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ProcViewController") as? ProcViewController{ procVC.procViewDelegate = self self.present(procVC, animated: true, completion: nil) } } }

procVC를 present할 때 delegate = self를 하면 준비가 끝난다. procVC에서 dismiss를할때 didBtnCliced 함수를 호출하기 때문에, dismiss된 이후에 didBtnCliced(data: String)을 타게 된다.


[결과]



첫 화면



startActivityForResult 버튼을 눌러 호출된 ProcViewController



ProcViewController에서 Click! 버튼을 눌러 dismiss된 후, data send라는 String값을 넘겨받았다.