안녕하세요! 후르륵짭짭 입니다.
이번에는 Delegate와 Delegate를 활용해서 ViewController 간의 데이터 전송 방법을 배워보려 합니다.
ViewController간에 DataPass 방법에는 총 3가지가 있습니다.
1. Notification을 이용한 방법
2. Segue와 Clouser을 이용한 방법
3. Delegate를 이용한 방법
이번에는 위에서 말한 것 처럼 3번째 방법을 알려드릴려고 합니다.
** Delegate란 무엇이지?? **
일단 Delegate 방법을 이용하려면 Delegate가 무엇인지 알아야합니다.
delegate는 단어 뜻의 의마가 대표자 또는 위임자라는 뜻으로 정의 되어 있습니다.
그러니깐, 어떤 역할의 대신해주는 위임자 역할일 수도 있고 대표자가 될 수도 있는 것을 의미합니다.
예전에 Delegate에 대한 글을 남겼는데요,
hururuek-chapchap.tistory.com/14?category=909177
여기에 나온 코드를 보면
ViewController는 StudentInfoSheet 프로토콜을 상속 받고 있고 Person 객체는 studentInfoSheet라는 인스턴스를 가지고 있습니다.
그리고 ViewController에서 Person 객체를 생성하고 그 Person객체의 delegate에 자기 자신을 넣어준 것을 볼 수 있습니다.
즉, 쉽게 설명하면 Person 객체가 할 일을 ViewController가 대신하게 되는 것 입니다.
그럼 실제로 사용해보도록 하겠습니다
** 실제로 사용해보기 **
일단 위에 처럼 UI를 구성해주세요!
//FirstViewController
class FirstViewController: UIViewController {
@IBOutlet weak var titleLabel: UILabel!
@IBOutlet weak var textField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
setTextFieldDelegate()
// Do any additional setup after loading the view.
}
//Connect By Segue
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "Segue"{
guard let vc = segue.destination as? SecondsViewController else {return}
vc.updateTitleLabel(input: textField.text!)
vc.delegate = self //내가 너의 일을 대신해줄게
}
}
//Button that perform segue ans check textField is empty
@IBAction func sendDatabtn(_ sender: Any) {
if textField.text != ""{
performSegue(withIdentifier: "Segue", sender: nil)
}
}
}
//function which is related with TextField
extension FirstViewController : UITextFieldDelegate {
func setTextFieldDelegate(){
self.textField.delegate = self
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
}
}
//perform delegate function
extension FirstViewController : sendDataDelegate {
//change TextLabel
func sendDatafunction(input: String) {
titleLabel.text = input
}
}
이건 위에 진한 보락새 ViewController 입니다. 처음 시작하는 ViewController이죠!
//SendDataDelegate Protocol
protocol sendDataDelegate : class {
func sendDatafunction(input : String)
}
//Second ViewContoller
class SecondsViewController: UIViewController {
@IBOutlet weak var titleLabel: UILabel!
@IBOutlet weak var textField: UITextField!
var tempString : String = ""
weak var delegate : sendDataDelegate?
override func viewDidLoad() {
super.viewDidLoad()
setTextFieldDelegate()
// Do any additional setup after loading the view.
}
override func viewDidLayoutSubviews() {
titleLabel.text = tempString
}
func updateTitleLabel(input : String){
tempString = input
}
//pass Data to previous ViewController with delegate
@IBAction func backToVcBtn(_ sender: Any) {
if textField.text != "" && delegate != nil{
//send data to protocol
delegate?.sendDatafunction(input: textField.text!)
dismiss(animated: true, completion: nil)
}
}
}
extension SecondsViewController : UITextFieldDelegate {
func setTextFieldDelegate(){
self.textField.delegate = self
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
}
}
아주 긴 코드가 있지만 결국 봐야할 것은 몇개 안 됩니다!
일단 Delegate를 사용하기 위해서는 프로토콜을 생성해줘야합니다.
protocol sendDataDelegate : class {
func sendDatafunction(input : String)
}
sendDataDelegate는 Class만 사용할 수 있는 프로토콜이고
이 프로토콜을 상속 받은 클래스는 sendDataFunction 기능을 사용해야합니다.
class SecondsViewController: UIViewController {
weak var delegate : sendDataDelegate?
override func viewDidLoad() {...}
override func viewDidLayoutSubviews() {...}
func updateTitleLabel(input : String){...}
@IBAction func backToVcBtn(_ sender: Any) {
if textField.text != "" && delegate != nil{
//send data to protocol
delegate?.sendDatafunction(input: textField.text!)
dismiss(animated: true, completion: nil)
}
}
}
위에 코드를 보면 sendDataDelegate 인스턴스를 생성 했습니다.
그러면 delegate는 sendDatafunction()을 사용할 수 있게 되고 textField.text를 보내줍니다.
하지만! SecondView Controller에서 이 기능을 사용하지 않습니다.
왜냐하면 SecondView Controller는 delegate 인스턴스를 가지고 있고 이 함수는 다른 누군가가 대신 위임해서 사용해줄 겁니다.
class FirstViewController: UIViewController {
override func viewDidLoad() {...}
//Connect By Segue
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "Segue"{
guard let vc = segue.destination as? SecondsViewController else {return}
vc.updateTitleLabel(input: textField.text!)
vc.delegate = self //내가 너의 일을 대신해줄게
}
}
//Button that perform segue ans check textField is empty
@IBAction func sendDatabtn(_ sender: Any) {...}
}
//function which is related with TextField
extension FirstViewController : UITextFieldDelegate {.....}
//perform delegate function
extension FirstViewController : sendDataDelegate {
//change TextLabel
func sendDatafunction(input: String) {
titleLabel.text = input
}
}
이제 FirstViewController를 보면 prepare를 사용한 것을 볼 수 있습니다.
segue를 통해 이동한다면 secondViewController가 메모리에 올라가고
그 순간에 secondViewController의 delegate를 FirstViewController로 넣어줍니다.
이렇게 하면 FirstViewController가 SecondViewController의 delegate의 역할을 대신 위임 받아서 하게 해줍니다.
따라서 마지막에 sendDataFuntion에서 그 기능을 수행하게 됩니다.
잘 이해가 되실지는 모르겠지만, 위에서 한 내용을 그대로 하시면 잘 이해가 될 것 입니다!!!
소스 코드 : github.com/HururuekChapChap/Xcode_TestProj/tree/master/DelegateDataPass/DelegateDataPass
참고 사이트 :
뷰 끼리 데이터를 전송 할 수 있는 방법 3가지
fluffy.es/3-ways-to-pass-data-between-view-controllers/
Delegate로 데이터를 전송하는 방법
Delegate란 무엇인가
Delegate의 자세한 설명 1
magi82.github.io/ios-delegate/
Delegate의 자세한 설명 2
velog.io/@iwwuf7/Swift-Delegate-Pattern에-대해서
delegate를 weak으로 설정했을 때 발생하는 오류
jusung.github.io/classOnlyProtocol/
키보드 오류 해결
hururuek-chapchap.tistory.com/31?category=909178
ARC에 대해서
velog.io/@delmasong/ARCAutomatic-Reference-Counting
'Xcode > Swift - PlayGround' 카테고리의 다른 글
PlayGround) DispatchGroup이란??? (0) | 2020.11.08 |
---|---|
PlayGround) IOS의 Unit Test에 대해 알아보자 (0) | 2020.11.05 |
PlayGround ) Swift로 RC4 알고리즘에 대해 알아보자! (0) | 2020.10.05 |
PlayGround ) Design Pattern (MVC) (0) | 2020.10.02 |
PlayGround ) Viewcontroller Life Cycle 이란?? (0) | 2020.09.30 |
댓글