Swift 일기장 개발 일기 1 (View 이동에서의 Data pass)

송민준·2022년 12월 28일
0

일기장 개발 일기

목록 보기
1/11

제가 Swift 개발을 하면서 멈칫했던 부분과 어떻게 해결했었는지 블로그에 남겨보고자 합니다.

하고자 하는 것


왼쪽은 MainViewController이며 생성버튼을 눌렀을 때 오른쪽 CreateViewController로 넘어갑니다.

따라서 생성버튼에 Ctrl+마우스 입력으로 Segue를 생성했습니다.
여기까지는 UI만으로도 쉽게 구현이 가능하고 CreateViewController로 넘어가는 것을 확인했습니다.

제가 하고자 하는 것은 CreateViewController에서 유저에게 정보를 입력받은 다음 그 정보를 MainViewController에 넘기는 것입니다.

해결방법은 DelegatePattern에서 찾았습니다.

Delegate Pattern

Delegate Pattern의 핵심은 Delegate 단어 그대로 "위임"입니다.
저는 MainVC에서의 프로퍼티와 메서드를 CreateVC에서 행하는 것으로 이해했습니다.
개린이의 입장에서 다음의 구현방법은 꽤 간단하지만 생각치도 못한 방법이라서 뒤통수 맞은 느낌이 었습니다.

핵심적인 코드들을 살펴봅시다.

MainViewController

import UIKit
protocol SendDataDelegate{
    func receiveData(responce: String) -> Void
}
class MainViewController: UIViewController, SendDataDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Do any additional setup after loading the view.
    }
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "CreateSegue"{
            guard let vc = segue.destination as? CreateViewController else { return }
            vc.dataDelegate = self
        }
    }
    @IBAction func createButtonClicked(_ sender: Any) {
        performSegue(withIdentifier: "CreateSegue", sender: nil)
    }
    func receiveData(responce: String) {
        print("receive: \(responce)")
    }
}

protocol SendDataDelegate{
    func receiveData(responce: String) -> Void
}

먼저 프로토콜을 만듭니다.
프로토콜을 MainVC가 상속받으면 다른 어떤 클래스는 SendDataDelegate 타입으로 MainVC를 받을 수 있으며 굳이 MainVC가 아니어도 receiveData() 함수가 있다는 것 자체만 알고 다른 구현들은 신경쓰지 않아도 됩니다. 그 결과로 낮은 결합도가 부여됩니다.


func receiveData(responce: String) {
        print("receive: \(responce)")
    }

MainVC에서 Override한 receiveData 입니다.
이 receiveData는 CreateVC에서 사용됩니다.


override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "CreateSegue"{
            guard let vc = segue.destination as? CreateViewController else { return }
            vc.dataDelegate = self
        }
}

Segue가 Perform되기 전에 실행되는 메서드입니다.
조건문 안의 내용을 살펴보면

guard let vc = segue.destination as? CreateViewController else { return }

segue의 목적지에 해당하는 VC를 CreateViewController로 인스턴스화시킵니다.

vc.dataDelegate = self

그리고 그 인스턴스의 dataDelegate라는 변수를 self, 즉 MainVC로 지정합니다.
아래 CreateVC에서 나오겠지만 dataDelegate의 타입은 SendDataDelegate입니다.

CreateViewController

import UIKit

class CreateViewController: UIViewController {
    @IBOutlet weak var date: UIDatePicker!
    @IBOutlet weak var textEmotion: UITextField!
    
    @IBOutlet weak var textContent: UITextView!
    @IBOutlet weak var calanderSwitch: UISwitch!
    
    var dataDelegate: SendDataDelegate?
    override func viewDidLoad() {
        super.viewDidLoad()
        print("createView is Created")
        // Do any additional setup after loading the view.
    }
    
    @IBAction func completeButtonPushed(_ sender: UIButton) {
        guard let content = textContent?.text else {return}
        dataDelegate?.receiveData(responce: content)
        dismiss(animated: true)
    }
    
}

var dataDelegate: SendDataDelegate?

dataDelegate 변수는 MainVC에서 이 CreateVC의 인스턴스가 생성될 때 MainVC로 지정이 되었습니다.


@IBAction func completeButtonPushed(_ sender: UIButton) {
        guard let content = textContent?.text else {return}
        dataDelegate?.receiveData(responce: content)
        dismiss(animated: true)
}

CreateVC에서 완료버튼이 눌렸을 때 실행되는 메서드입니다.

UITextView(textContent)에서 문장이 있을 경우에 dataDelegate의 receiveData의 인자가 됩니다.

결과


profile
개발자

0개의 댓글