[Xcode / Swift] ViewController간 데이터 교환하기

ViewController간에 데이터를 보내는 방법이다.


시작

FirstViewController.swift

첫 화면은 아래와 같이 설정되었다(storyboard 왼쪽의 작은 화살표는 시작 화면을 의미). Class 이름은 미리 FirstViewController로 수정해놓았다. 혹 Class 이름을 변경하다 Outlet과 UI Element들의 연결이 끊어진 경우가 생겼다면 아래 링크를 참조바란다.

  • [Xcode / Swift] ViewController 이름 변경 시 유의사항

  • UILabel : receivedText, Outlet으로 연결
  • UITextField : textField, Outlet으로 연결
  • UIButton : sendText, Action으로 연결
import UIKit

class FirstViewController: UIViewController {

    @IBOutlet weak var receivedText: UILabel!
    @IBOutlet weak var textField: UITextField!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


    @IBAction func sendText(_ sender: UIButton) {
        
    }
}

SecondViewController.swift

두번째 화면 설정. SecondViewController.swift파일을 만들고, custom Class를 SecondViewController로 연결해야함.

  • UILabel : receivedText, Outlet으로 연결
  • UITextField : textField, Outlet으로 연결
  • UIButton : returnWithText, Action으로 연결
import UIKit

class SecondViewController : UIViewController{
    
    @IBOutlet weak var receivedText: UILabel!
    @IBOutlet weak var textField: UITextField!
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    @IBAction func returnWithText(_ sender: Any) {
        
    }
}

작업 시작

Segue 연결

First View Controller에서 우클릭으로 잡고 Second View Controller로 놓은 후, Show를 선택.

Segue를 선택한 후 Attribute Inspector에서 Identifier를 지정해준다. 필자의 경우, “showSecondView“이다.

단방향 코드 작업(First -> Second)

FirstViewController.swift

  • @IBAction func sendText(_ sender: UIButton) : performSegue 함수를 이용하여 showSecondView를 Call한다.
  • override func prepare(for segue: UIStoryboardSegue, sender: Any?) 함수 추가
    @IBAction func sendText(_ sender: UIButton) {
        performSegue(withIdentifier: "showSecondView", sender: self)
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        
        if segue.identifier == "showSecondView"{
            
            let secondVC = segue.destination as! SecondViewController
            
           secondVC.data = textField.text!
            
        }
    }

SecondViewController.swift

  • var data = “” 추가
  • 넘겨받은 data receivedText.text에 입력
    var data = ""
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        receivedText.text = data
    }

양방향 작업

단방향으로 만든 segue를 하나 더 추가하여 ViewController를 Load하는 방법은 사용해서는 안된다. 이는 View를 Stack으로 쌓아서 뒤에 열렸던 뷰가 A이면 B에서 부르는 뷰가 A1가 되고 A1은 B1을 부르게 되고 B1은 A2를 또 부르게 된다. 즉, A에 입력되었던 값은 A1을 부르면서 모두 사라진다.

data를 전달하는 protocol을 구현한 후, FirstClass에서는 Conform한다. 처음 segue가 불릴 때, delegate를 self로 해주어야 한다. secondViewController의 delegate가 nil이면 아무것도 하지 않는다. 즉, 2번째에서 1번째로 되돌아올 때, Data를 포함하지 않는다.

FirstViewController.swift – 아래 빨간색 코드 참조

import UIKit

class FirstViewController: UIViewController, sendBackDelegate {
    

    @IBOutlet weak var receivedText: UILabel!
    @IBOutlet weak var textField: UITextField!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


    @IBAction func sendText(_ sender: UIButton) {
        performSegue(withIdentifier: "showSecondView", sender: self)
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        
        if segue.identifier == "showSecondView"{
            
            let secondVC = segue.destination as! SecondViewController
            secondVC.data = textField.text!
            secondVC.delegate = self
            
        }
    }
    func dataReceived(data: String) {
        receivedText.text = data
    }
}

SecondViewController.swift – 아래 빨간색 코드 참조

import UIKit

protocol sendBackDelegate {
    func dataReceived(data: String)
}

class SecondViewController : UIViewController{
    
    @IBOutlet weak var receivedText: UILabel!
    @IBOutlet weak var textField: UITextField!
    
    var data = ""
    var delegate : sendBackDelegate?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        receivedText.text = data
        
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    @IBAction func returnWithText(_ sender: Any) {
        
        delegate?.dataReceived(data: textField.text!)
        dismiss(animated: true, completion: nil)
    }
}

구현 GIF

아래와 데이터를 잘 받고 넘긴다.

댓글 남기기