iOS

[ iOS ] 데이터 전달 : (2/5) DelegatePattern으로 전달하기

Forest Yun 2022. 6. 20. 21:04
728x90

문제

다양한 방법으로 데이터 전달하기

 

 

1. Property로 전달하기

2. DelegatePattern으로 전달하기

3. NotificationCenter로 전달하기

4. Closure로 전달하기

5. 장단점 정리

 

 

 

 

 

 

 

 

 

 

 

 


 

 

 

 

 

 

 

 

 

DelegatePattern으로 전달하기

2 - 1  화면 전환 시 데이터를 전달하는 데에 여러가지 방법이 있는데, 그 중 Delegate Pattern을 사용해 데이터를 전달하는 방법을 알아보자.

2의 ViewController에서 Delegate 프로토콜을 선언해 화면 전환 버튼의 액션함수에서 방금 선언해준 Delegate의 메서드를 호출한다. 이 메서드의 구현은 1의 ViewController에서 이루어진다. 메서드 호출 시 데이터를 인수로 넘겨주고, 구현 부분에서는 매개변수를 원하는 곳에 할당한다. 이렇게 되면 2 화면에서 1 화면으로 데이터를 전달할 수 있다.

 

 

 

 

 

 

 

 

먼저 2의 ViewController에 Delegate 프로토콜을 선언한다. 프로토콜 안에는 메서드를 선언하는데, 데이터를 담을 매개변수도 함께 선언한다. 그리고 해당 ViewController에 작업을 위임해줄 delegate 프로퍼티를 선언한다.

import UIKit

protocol DelegatePatternViewControllerDelegate: AnyObject {
    func passContent(_ content: String?)
}

class DelegatePatternViewController: UIViewController {
    //MARK: - 아울렛 변수
    @IBOutlet weak var contentLabel: UILabel!
    @IBOutlet weak var contentTextField: UITextField!
    
    //MARK: - 프로퍼티
    var content: String?
    weak var delegate: DelegatePatternViewControllerDelegate?
    
    ...
}
  • delegate는 순환참조를 방지하기 위해 weak로 선언되어야 하는데, weak는 구조체, 열거형 등 클래스가 아닌 곳에서는 사용될 수 없다. 따라서 Delegate 프로토콜에 AnyObject를 상속하여 클래스에만 사용할 것임을 명시해준다.

 

 

이전 화면으로 돌아가는 버튼의 액션함수를 생성한다. 그 안에는 위에서 선언한 delegate의 메서드를 호출한다. 호출 시 데이터는를인자로 넘겨준다. 그리고 이전 화면으로 돌아가기 위해 popViewController를 호출한다. 

class DelegatePatternViewController: UIViewController {
    ..
    
    //MARK: - 액션 함수
    @IBAction func tapPreviousButton(_ sender: UIButton) {
        self.delegate?.passContent(self.contentTextField.text) //데이터 전달
        
        self.navigationController?.popViewController(animated: true)
    }
}

 

 

1의 화면에서 아까 선언한 Delegate 프로토콜을 채택하고 passContent(_:)를 구현한다. 여기서 매개변수를 content 변수에 할당해 데이터를 전달받는다.

import UIKit

class PropertyViewController: UIViewController {
    //MARK: - 아울렛 변수
    @IBOutlet weak var contentTextField: UITextField!
    @IBOutlet weak var contentLabel: UILabel!
    
    //MARK: - 프로퍼티
    var content: String?
    
    //MARK: - 라이프 사이클
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        configureView()
    }
    
    ...
}

extension PropertyViewController: DelegatePatternViewControllerDelegate {
    func passContent(_ content: String?) {
        self.content = content
    }
}

 

 

 

 

마지막으로 1의 ViewController가 2의 일을 위임받아야 하는데, 이 작업은 1 - 2로 화면이 넘어갈 때 이루어진다.

	//MARK: - 액션 함수
    @IBAction func tapNextButton(_ sender: UIButton) {
        let storyboard = UIStoryboard(name: "DelegatePattern", bundle: Bundle.main)
        guard let delegatePatternViewController = storyboard.instantiateViewController(withIdentifier: "DelegatePatternViewController") as? DelegatePatternViewController else {return}
        
        //위임받기
        delegatePatternViewController.delegate = self
        
        delegatePatternViewController.content = self.contentTextField.text
        
        self.navigationController?.pushViewController(delegatePatternViewController, animated: true)
    }

 

 

 

 

 


 

 

 

 

 

 

728x90