티스토리 뷰

Switching View and Passing Data(2) - Code


안녕하세요. 오늘은 unwind를 이용한 데이터 전달에 이어 Delegate를 활용한 데이터 전달에 대해 보도록 하겠습니다.

이 글을 읽어보시기 전 반드시. DelegateUITableView에 관한 지식이 있으셔야 합니다. 제가 포스팅한 글도 있으니 참고하시기 바랍니다.


그리고 본 포스팅은 이전 포스팅을 바탕으로 작성하였습니다.


그럼 본격적으로 시작해보도록 하겠습니다.


UI 구성은 위의 UI 세팅 내용을 그대로 사용하였기 때문에 다루지 않도록 하겠습니다.


1. Basic Setting

먼저 ViewControllerAddViewController의 요소들을 각각 IBOutlet으로 연결시켜 줍니다. 물론 AddViewControllerSave 버튼은 IBAction으로 연결하는 것을 잊지마세요!


ViewController.swift > ViewController.class

class ViewController: UIViewController, UITableViewDataSource{

    @IBOutlet weak var friendListTableView: UITableView!
    
    private var friendList = [[String:String]]()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        friendListTableView.dataSource = self
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return friendList.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath)
  	-> UITableViewCell {
        let cell = tableView.dequeueReusableCell(
          withIdentifier:"friendcell",
          for: indexPath)
        return cell
    }
}

  1. 먼저 친구들의 데이터를 딕셔너리의 배열의 형태로 key-value형식으로 저장할 것이기 때문에 다음과 같이 friendList를 선언해주었습니다.
  2. 항상 friendListTableView.dataSource = self 작성해주는 것을 잊지마세요.

  • 위에서 언급하였듯이 TableView나 관련 프로토콜에 대한 설명은 이 포스팅에서는 다루지 않도록 하겠습니다.

AddViewController.swift > AddViewController.class

class AddViewController: UIViewController {

    @IBOutlet weak var nameTextField: UITextField!
    @IBOutlet weak var phoneTextField: UITextField!
    
    override func viewDidLoad() {
        super.viewDidLoad()

    }
    @IBAction func saveBtnTapped(_ sender: Any) {
      
    }
}

이렇게 기본적인 세팅은 끝났습니다. 이제 본격적으로 코드를 작성해보도록 하겠습니다.


2. Protocol and Delegate

이번 포스팅에서는 Delegate 를 통해 데이터를 전달해줄 것이라고 말씀드렸습니다. 제가 Delegate 포스팅에서도 언급했듯이 Delegate는 객체간의 상호작용이고 이러한 상호작용 중 하나인 데이터 전달해볼 것입니다.


Delegate를 사용할 때는 다음의 세가지가 필요합니다.


  1. Protocol - 일의 목록
  2. Delegate - 일을 해주는 객체
  3. Master - 일을 위임하는 객체

즉 이번 예제에서는 AddViewController 가 일을 위임하는 객체가 되는 것이고, ViewController가 일을 하는 객체가 되는 것입니다.


그러면 이제 일의 목록, 즉 Protocol을 만들어보도록 하겠습니다.

protocol SaveDataDelegate:class {
    func saveData(data saveData:[[String:String]])
}

프로토콜을 정의해주었으면 일을 위임하는 객체(AddViewControleller)에서 일을 대신할 객체를 참조할 변수를 선언합니다.

그리고 AddViewController에서 Save 버튼을 누르면 현재 친구를 추가하는 화면은 내려가고 데이터가 저장되어야 하기 때문에 다음과 같이 코드를 작성합니다. 그리하여 완성된 AddViewController는 다음과 같습니다.


AddViewController.swift > AddViewController.class

import UIKit

protocol SaveDataDelegate:class{
    func saveData(data saveData:[String:String])
}
class AddViewController: UIViewController {

    weak var delegate:SaveDataDelegate?
    
    @IBOutlet weak var nameTextField: UITextField!
    @IBOutlet weak var phoneTextField: UITextField!
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    @IBAction func saveBtnTapped(_ sender: Any) {
      	var data = [String:String]()
        data["name"] = nameTextField.text!
        data["phone"] = phoneTextField.text!
        delegate?.saveData(data: data)
      	self.navigationController?.popViewController(animated: true)
    }
}

이렇게 하면 AddViewController 에서의 작업은 끝이 납니다.

그럼 이제 ViewController, 즉 실질적으로 데이터를 저장하는 곳에서 함수를 작성해보도록 하겠습니다.


ViewController.swift > ViewController.class

func saveData(data saveData: [String : String]) {
  	friendList.append(saveData)
  	friendListTableView.reloadData()
}

간단하죠? 하지만 여기서 문제가 있습니다. 바로 어떻게 AddViewControllerViewController을 "고용" 관계를 설정하냐 입니다. TableViewIBOulet으로 참조 변수를 생성하여 연결시켰지만 AddViewController는 어떻게 연결시켜야 할까요?


바로 prepare(segue:sender:) 함수를 이용하는 것입니다. 우리가 스토리보드에서 지정한 SegueAdd 버튼을 눌렀을 때 ViewController에서 AddViewController로 넘어가는 Segue였습니다. Segue객체에는 기본적으로 출발지(source)와 목적지(destination)이 프로퍼티로 존재합니다. 저는 그것을 활용할 것입니다.


ViewController.swift > ViewController.class

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
  	let destination = segue.destination as! AddViewController
  	destination.delegate = self
}

prepare(segue:sender:)함수는 Segue가 발동될 때 (이 예제에서는 Add 버튼이 눌렸을 때) 자동으로 호출되는 함수이고 Segue에는 sourcedestination 프로퍼티가 존재함으로 다음과 같이 prepare(segue:sender:) 함수안에서 destination.delegate = self를 해주었습니다.


그리고 마지막으로 Cell에 데이터를 뿌려주는 코드를 작성하도록 하겠습니다. 먼저 스토리보드로 들어가셔서 TableViewCell을 선택하시고 셀의 스타일을 Subtitle로 지정해주세요. 그리고 이제 다음과 같이 작성해주세요.


ViewController.swift > ViewController.class

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath)
-> UITableViewCell {
  let cell = tableView.dequeueReusableCell(withIdentifier: "friendcell", for: indexPath)
  cell.textLabel?.text = friendList[indexPath.row]["name"]!
  cell.detailTextLabel?.text = friendList[indexPath.row]["phone"]
  return cell
}


마무리

이렇게 오늘은 Delegate를 활용한 데이터 전달을 알아보았습니다. 이렇게 Delegate를 공부하실 때 이것이 정확히 언제 사용되고 내부는 어떻게 돌아가는거지 라고 생각했던 분들은 많은 도움이 됬을 것이라고 생각합니다. 실제로 저도 이해하는데 상당히 많은 도움이 됬구요! 그럼 다음 포스팅에서 뵙겠습니다. 감사합니다!




Source : github


참고자료


  1. Passing Data Between View Controllers in iOS: the Definitive Guide (Best Practices + Examples)


'Swift + iOS > iOS' 카테고리의 다른 글

[ios] UserDefaults를 이용한 데이터 저장  (0) 2017.12.05
[ios] AppDelegate.swift  (0) 2017.12.01
[ios] NotificationCenter  (0) 2017.11.20
[ios] Auto Layout Programmatically - 2  (0) 2017.11.20
[ios] Storyboard Reference  (0) 2017.11.20
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함