데이터를 전달하는 방법

Yoon Yeoung-jin·2022년 3월 9일
0

iOS 개발

목록 보기
4/11

  • ViewController.swift
//
//  ViewController.swift
//  reviewProject2
//
//  Created by yoon-yeoungjin on 2022/03/09.
//

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        /* notification 활용 부분 */
        let notificationName = Notification.Name("sendSomeString")
        NotificationCenter.default.addObserver(self, selector: #selector(showSomeString), name: notificationName, object: nil)  /* 지정한 notification의 이름에 해당되는 놈을 감시하도록 선언 */
        
        /* notification 중 키보드 올라올 경우 나오는 것에 대한 예제 */
        NotificationCenter.default.addObserver(self, selector: #selector(KeyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
    }
    
    /* notification 제공 메소드 중 키보드에 대한 것 테스트 함수 */
    @objc func KeyboardWillShow(){
        self.ChangeLabel.text = "will shoe :)"
    }
    
    /* notification 을 활용할 objc 함수 선언 */
    @objc func showSomeString(notification: Notification) {
        if let str = notification.userInfo?["str"] as? String {
            self.ChangeLabel.text = str
        }
    }
    
    /*
      1. instance property
        - 해당 인스턴스 안에 있는 변수에 직접적으로 데이터를 전달하는 방법
        - 해당 예시에서는 DetailViewController 안에 someString 변수가 선언되어있음
        - 아래 예시처럼 데이터를 전달 가능.
    */
    @IBAction func moveToDetail(_ sender: Any) {
        let detailVC = DetailViewController(nibName: "DetailViewController", bundle: nil)
        detailVC.someString = "만나서 반가워요 :)"
        self.present(detailVC, animated: true, completion: nil)
    }
    
    /*
      2. segue
        - segue 란: 스토리보드에서 뷰 컨트롤러 사이의 화면전환을 위해 사용하는 객체
        - 해당 화면으로 전환하기 위해서는 세그의 identifier를 설정하고 이를 토대로 구분한다.
        - 전환하기 위해서는 prepare 함수를 사용한다.
        -
    */
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "segueDetail" {
            if let detailVC = segue.destination as? SegueViewController {   /* 해당 도착지의 형태가 SegueViewController으로 정의 되어있으면 아래 문구 실행 */
                detailVC.someString = "만나서 반가워요 :)"
            }
        }
    }
    
    @IBOutlet weak var ChangeLabel: UILabel!
    /*
      3. instance 통으로 넘겨줘서 그 인스턴스 안에 직접 접근할 수 있게 만드는 것
        - InstanceDetailViewController 안에 메인 class를 받을 수 있는 객체를 선언해 놓는다.
        - 해당 객체를 받아서 이 객체 안에 있는 라벨의 값을 사용한다.
    */
    @IBAction func moveToInstance(_ sender: Any) {
        let detailVC = InstanceDetailViewController(nibName: "InstanceDetailViewController", bundle: nil)
        detailVC.mainVC = self
        self.present(detailVC, animated: true, completion: nil)
    }
    /*
      4. delegate pattern 사용
        - 뷰 컨트롤러 안에 패턴을 만들어서 사용하는 방법
        - 해당 패턴의 함수는 mainVC 에서 extention을 통해 선언한다.
        - 해당 함수를 통해서 ChangeLabel 값을 변경한다.
        - 호출하는 곳과 구현하는 곳이 나뉘어져 있다.
    */
    @IBAction func moveToDelegate(_ sender: Any) {
        let detailVC = DelegateDetailViewController(nibName: "DelegateDetailViewController", bundle: nil)
        detailVC.delegate = self    /* 자기 자신을 넘겨주는 것 처럼 보이지만 이거는 delegate의 형식에 해당되는 놈만 전달된다. */
        self.present(detailVC, animated: true, completion: nil)
    }
    /*
      5. closure 사용
        - 뷰 컨트롤러 안에 closure를 만들어서 사용하는 방법
        - 해당 closure 선언은 해당 뷰 컨트롤러가 아닌 밖에서 선언한다.
        - 해당 closure을 통해서 ChangeLabel 값을 변경한다.
        - 호출하는 곳과 구현하는 곳이 나뉘어져 있다.
    */
    @IBAction func moveToClosure(_ sender: Any) {
        let detailVC = ClosureDetailViewController(nibName: "ClosureDetailViewController", bundle: nil)
        detailVC.myClosure = { str in
            self.ChangeLabel.text = str
        }
        self.present(detailVC, animated: true, completion: nil)
    }
    /*
      6. notification
        - notification 함수를 이용해서 @objc 타입의 함수를 선언
        - name 을 타겟팅으로 다른 클래스에서 notification으로 함수를 사용할 수 있다.
        - 데이터는 userInfo를 통해서 주고 받을 수 있다.
        - userInfo의 타입은 dictionary 타입이고 value 값은 any 타입이다.
        - 데이터 전송은 .post 를 활용한다.
    */
    @IBAction func moveToNotification(_ sender: Any) {
        let detailVC = NotiDetailViewController(nibName: "NotiDetailViewController", bundle: nil)
        self.present(detailVC, animated: true, completion: nil)
    }
}

/* delegate 의 예시 확장 함수 */
extension ViewController: DelegateDetailViewControllerDelegate {
    func passString(string: String){
        self.ChangeLabel.text = string
    }
}
  • DetailViewController.swift
//
//  DetailViewController.swift
//  reviewProject2
//
//  Created by yoon-yeoungjin on 2022/03/09.
//

import UIKit

class DetailViewController: UIViewController {
    var someString = "" /* 외부에서 값을 받기 위한 변수 */
    @IBOutlet weak var someLabel: UILabel! /* 화면에 지정해놓은 라벨의 변수 */
    override func viewDidLoad() {
        super.viewDidLoad()
        someLabel.text = someString
    }
    
    @IBAction func exit(_ sender: Any) {
        self.dismiss(animated: true, completion: nil)
    }
}
  • DelegateDetailViewController.swift
//
//  DelegateDetailViewController.swift
//  reviewProject2
//
//  Created by yoon-yeoungjin on 2022/03/09.
//

import UIKit

protocol DelegateDetailViewControllerDelegate: AnyObject {
    func passString(string: String)
}

class DelegateDetailViewController: UIViewController {
    
    weak var delegate: DelegateDetailViewControllerDelegate?

    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    @IBAction func ChangeLabel(_ sender: Any) {
        delegate?.passString(string: "DelegateDetailViewController :)")
        self.dismiss(animated: true, completion: nil)
    }
    
    @IBAction func exit(_ sender: Any) {
        self.dismiss(animated: true, completion: nil)
    }
}
  • ClosureDetailViewController.swift
//
//  ClosureDetailViewController.swift
//  reviewProject2
//
//  Created by yoon-yeoungjin on 2022/03/09.
//

import UIKit

class ClosureDetailViewController: UIViewController {
    
    var myClosure: ((String) -> Void)?
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    @IBAction func ChangeLabel(_ sender: Any) {
        myClosure?("ClosureDetailViewController :)")
        self.dismiss(animated: true, completion: nil)
    }
    @IBAction func exit(_ sender: Any) {
        self.dismiss(animated: true, completion: nil)
    }
}
  • NotiDetailViewController.swift
//
//  NotiDetailViewController.swift
//  reviewProject2
//
//  Created by yoon-yeoungjin on 2022/03/09.
//

import UIKit

class NotiDetailViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
    }
    @IBAction func ChangeLabel(_ sender: Any) {
        let notificationName = Notification.Name("sendSomeString")
        let strDic = ["str": "NotiDetailViewController :)"]
        NotificationCenter.default.post(name: notificationName, object: nil, userInfo: strDic)
        self.dismiss(animated: true, completion: nil)
    }
    @IBAction func exit(_ sender: Any) {
        self.dismiss(animated: true, completion: nil)
    }
}
  • InstanceDetailViewController.swift
//
//  InstanceDetailViewController.swift
//  reviewProject2
//
//  Created by yoon-yeoungjin on 2022/03/09.
//

import UIKit

class InstanceDetailViewController: UIViewController {
    
    var mainVC: ViewController?

    override func viewDidLoad() {
        super.viewDidLoad()
    }
    @IBAction func ChangeLabel(_ sender: Any) {
        mainVC?.ChangeLabel.text = "InstanceDetailViewController :)"
        self.dismiss(animated: true, completion: nil)
    }
    @IBAction func exit(_ sender: Any) {
        self.dismiss(animated: true, completion: nil)
    }
}

화면

profile
신기한건 다 해보는 사람

0개의 댓글