버그 잡이

iOS 화면 전환 간 데이터 전달 방법 본문

IOS

iOS 화면 전환 간 데이터 전달 방법

버그잡이 2020. 8. 4. 21:36

오늘은 view controller 간 데이터를 주고 받는 방법에 대해서 알아보겠습니다.

 

크게 세 가지 방법이 있습니다.

 

  1. present, push를 활용한 방법
  2. segue를 활용한 방법
  3. 프로토콜을 활용한 방법

 

present, push 를 활용한 방법

 

방법은 다음과 같습니다.

 

  1. firstVC 에서 nextBtn 클릭시, NextVC로 이동하는 코드를 짭니다.
  2. 이때 NextVC의 파라미터인 paramEmail에 원하는 데이터를 넣은 후 present(또는 push) 합니다.
//firstVC
@IBAction func nextBtn(_ sender: Any) {
    if let nextVC = self.storyboard?.instantiateViewController(withIdentifier: "NextVC") as? NextVC {
    
        nextVC.paramEmail = "기본 이메일"
        self.present(nextVC, animated: true)
    }  
}


//NextVC
var paramEmail: String = ""
    
override func viewDidLoad() {
    super.viewDidLoad()

    self.emailField.text = paramEmail 
}

 

push를 활용한 방법은 다음과 같습니다.

(물론 navigation controller를 embed 한 상태겠죠?)

let nextVC = self.storyboard?.instantiateViewController(withIdentifier: "NextVC")

nextVC.paramEmail = "기본 이메일"
self.navigationController?.pushViewController(nextVC!, animated: true)

 

 

 

Segue를 활용한 방법

 

segue를 활용하면 스토리보드 상에서 vc 간 전환이 연결되어 있습니다.

그렇기 때문에 1번 방법처럼 버튼 클릭시 데이터를 전달하는 것이 아니라

prepare() 라는 함수를 override 해서 구현합니다.

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    let destination = segue.destination
    
		//가고자 하는 VC가 맞는지 확인해줍니다.
    guard let nextVC = destination as? NextVC else {
        return
    }
    
    nextVC.paramEmail = "투투 이메일"
}

 

 

 

Delegation 을 활용한 방법

Delegation은 디자인 패턴 중 하나로, protocol을 활용하여 다른 컨트롤러에게 세부 구현을 위임하는 패턴입니다.

(이와 관련된 주제는 추후에 구체적으로 다루겠습니다.)

 

이는 양방향으로 데이터를 주고 받을 때 유용한 방법입니다.

 

방법은 아래와 같습니다.

 

1) 두 개의 view를 segue로 이어줍니다.

  • segue의 identifier를 정의합니다.
    • 스토리보드에서 해당 segue를 선택 후 attribute Inspector에 가면 이를 설정할 수 있습니다.

 

2) nextVC에서 프로토콜로 delegate를 정의하고 return button을 눌렀을 때 데이터를 넘겨주도록 정의합니다.

  • 프로토콜을 활용하면 java에 interface 처럼 특정 클래스에서 동작만 하고 다른 클래스에서 동작에 따른 구현을 나눠서 하게 할 수 있습니다.
  • 이전 VC에서 받은 getData를 return 버튼 클릭시 프로토콜을 통해서 넘겨주도록 하였습니다.
protocol returnDelegate {
    func dataReceived(data: String)
}

class NextViewController: UIViewController {
    @IBOutlet weak var nextLabel: UILabel!
    
    var getData = ""
    var delegate: returnDelegate?  //이 delegate를 통해서 protocol 간 연결이 이루어집니다.
    
    func transferDelegate(data: String) {
        self.nextLabel.text = data
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()

    }
    
    @IBAction func returnText(_ sender: Any) {
        
        delegate?.dataReceived(data: getData)
        dismiss(animated: true, completion: nil)
        
    }
}

 

 

3) firstVC에서 delegate를 채택하고, 그에 따른 메서드를 구현합니다.

  • returnDelegate를 채택 후 필요 메서드를 구현합니다.
  • 연결하고자 하는 VC의 delegate에 자신의 delegate를 연결해줍니다. (nextVC.delegate = self)
class ViewController: UIViewController, returnDelegate {
    
    var delegate: TransferDelegate?

    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        
        if segue.identifier == "toNextView" {
            let nextVC = segue.destination as! NextViewController
            nextVC.getData = "이 값이 돌아오길"
            nextVC.delegate = self  //연결하고자 하는 delegate에 해당 VC의 delegate를 연결해줍니다.
        }
    }

	//delegate 채택에 따른 필수 메서드 구현
    func dataReceived(data: String) {
        print(data)
    }
}

 

 

 

 

 

  • 참고

https://philosopher-chan.tistory.com/62

반응형
Comments