문제
다양한 방법으로 데이터 전달하기
2. DelegatePattern으로 전달하기
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)
}
'iOS' 카테고리의 다른 글
[ iOS ] UIButton.Configuration 사용하기(1) - Init, Title (iOS 15) (0) | 2022.10.13 |
---|---|
[iOS ] 데이터 전달 : (3/5) NotificationCenter로 전달하기 (0) | 2022.06.21 |
[ iOS ] 데이터 전달 : (1/5) Property로 전달하기 (0) | 2022.06.20 |
[ iOS ] 사진 선택 시 번호 표기(넘버링) 구현 (+ collectionView) (0) | 2022.06.15 |
[ iOS ] cell 내 버튼 선택 이벤트 구현 (+ Delegate 패턴) (0) | 2022.06.14 |