[iOS] 다른 뷰 컨트롤러와 데이터 주고받기

chaaansooo·2022년 5월 10일
0

iOS

목록 보기
2/8
post-thumbnail

화면 전환 과정에서의 값 전달 방식

뷰 컨트롤러 사이에 값을 주고받는 방식

  1. 뷰 컨트롤러에서 다음 뷰 컨트롤러로 직접 값을 전달
  2. 공통 저장소를 만들어 뷰 컨트롤러들이 저장소를 공유

직접 전달 방식(동기 방식)

  • 영속적으로 값을 저장할 필요가 없는 화면 전환에서 사용됨
  • 화면이 전환될 때 데이터가 함께 전달되거나 화면이 전환되기 전에 데이터가 미리 전달되므로 전달 과정에서 값이 누락될 염려가 없음
  • 비동기방식보다 코드가 간결해짐
  • 화면 전환과 값 전달이 함께 이루어짐
  • 전달받는 쪽의 뷰컨이 전달받을 값의 명세를 파악하고 변수를 미리 생성해놔야함
    -> 보내는 뷰컨이 받는 뷰컨에 대한 정보를 확인할 수 있어야 함

간접 전달 방식(비동기 방식)

  • 지속적으로 값을 저장할 필요가 있는 화면 전환에서 사용됨
  • 값을 계속 사용할 수 있게 저장해두기에 좋음
  • 저장소에 데이터가 저장되는 시점과 화면 전환 시점이 일치하지 않으면 값 전달이 제대로 안 될 수 있음
    -> 이에 대한 처리를 하며 코드가 길어질 수 있음
  • 화면 전환과 값의 전달이 따로 이루어짐
  • 받는 뷰컨과 보내는 뷰컨 모두 저장소의 위치를 사전에 공유해야함
  • 값 전달보다는 값을 저장하는 느낌이다~

뷰컨트롤러에 직접 값을 전달하기

전달하는 과정

첫번째 방식: 프레젠테이션 방식으로 화면 전환하며 값 전달
1. 뷰컨1에서 뷰컨2로 전달할 값을 준비
2. 뷰컨 2에서 값을 대입받을 프로퍼티(변수) 미리 정의
3. 뷰컨1에서 뷰컨2의 인스턴스 직접 생성 or 이미 생성된 인스턴스 참조 읽어옴

  • 프레젠테이션 방식이나 네비게이션 컨트롤러 방식으로 화면을 전환하기 위해서 스토리보드로부터 뷰컨의 인스턴스를 직접 생성하는 instantiateViewController() 메소드를 사용해야함
    guard let rvc = self.storyboard?.instantiateViewController(withIdentifier:"ID넣기") as? ResultViewController else { return }
    메소드나 프로퍼티를 사용하지 않는 화면 전환과 달리 ResultViewController 내의 프로퍼티에 접근해야하므로 다운캐스팅 해줘야한다
  • (세그웨이를 통해 화면을 전환한다면 세그웨이 객체가 뷰컨의 인스턴스를 생성해주므로 .destination 속성을 통해 인스턴스 참조를 읽어오기만 하면 됨)
  1. 뷰컨1에서 뷰컨2의 변수에 값을 대입
    rvc.paramName = self.sourceparam.text!
    이런 식으로 현재 뷰컨의 값을 다른 뷰컨의 파라미터에 전달한다.
    단, 레이블 객체에 직접 전달할 수 없고, 다른 변수에 삽입한 후, 뷰가 변경된 후 그 값을 레이블에 넣어줘야한다.
  2. 뷰컨1에서 2로 화면 전환
    self.present(rvc, animated: true)
    값을 전달해주고 화면을 전환
  3. 전환된 화면에서 변수 값을 레이블에 삽입

두번째 방식: 네비게이션 컨트롤러 방식으로 화면 전환하며 값 전달
1. 뷰컨1에서 뷰컨2로 전달할 값을 준비
2. 뷰컨 2에서 값을 대입받을 프로퍼티(변수) 미리 정의
3. 뷰컨1에서 뷰컨2의 인스턴스 직접 생성 or 이미 생성된 인스턴스 참조 읽어옴

  • 세그웨이를 통해 화면을 전환한다면 세그웨이 객체가 뷰컨의 인스턴스를 생성해주므로 .destination 속성을 통해 인스턴스 참조를 읽어오기만 하면 됨
  1. 뷰컨1에서 뷰컨2의 변수에 값을 대입
    rvc.paramName = self.sourceparam.text!
    이런 식으로 현재 뷰컨의 값을 다른 뷰컨의 파라미터에 전달한다.
    단, 레이블 객체에 직접 전달할 수 없고, 다른 변수에 삽입한 후, 뷰가 변경된 후 그 값을 레이블에 넣어줘야한다.
  2. 뷰컨1에서 2로 화면 전환
    self.navigationController?.pushViewController(rvc, animated: true)
    값을 전달해주고 화면을 전환
  3. 전환된 화면에서 변수 값을 레이블에 삽입

세번째 방식: 세그웨이를 이용하여 화면 전환하며 값 전달
1. 뷰컨1에서 뷰컨2로 전달할 값을 준비
2. 뷰컨 2에서 값을 대입받을 프로퍼티(변수) 미리 정의
3. 뷰컨1에서 뷰컨2의 인스턴스 직접 생성 or 이미 생성된 인스턴스 참조 읽어옴

  • 프레젠테이션 방식이나 네비게이션 컨트롤러 방식으로 화면을 전환하기 위해서 스토리보드로부터 뷰컨의 인스턴스를 직접 생성하는 instantiateViewController() 메소드를 사용해야함
    guard let rvc = self.storyboard?.instantiateViewController(withIdentifier:"ID넣기") as? ResultViewController else { return }
    메소드나 프로퍼티를 사용하지 않는 화면 전환과 달리 ResultViewController 내의 프로퍼티에 접근해야하므로 다운캐스팅 해줘야한다
  • 세그웨이를 통해 화면을 전환한다면 세그웨이 객체가 뷰컨의 인스턴스를 생성해주므로 .destination 속성을 통해 인스턴스 참조를 읽어오기만 하면 됨
  1. 세그웨이 전처리 메소드인 prepare(for: , sender:)를 사용하여 값을 전달
    세그웨이를 다룰 때는 dest뷰컨 인스턴스 자동으로 생성되기 때문에 우리가 임의로 생성하면 안됨.
    -> prepare 메소드를 override해서 segue.destination에다가 인자를 넣어주면 된다.
  2. 뷰컨1에서 2로 화면 전환
    self.performSegue(withIdentifier:"세그웨이 ID", sender: self)
    값을 전달해주고 화면을 전환
  3. 전환된 화면에서 변수 값을 레이블에 삽입

저장소를 이용하여 값 주고받기(비동기 방식)

AppDelegate를 사용해서 값 주고받기

  • 스크린이 다시 나타나는 시점에 값을 읽어와야 하므로 viewWillApear내부에 값을 읽고 표시하는 코드를 넣어준다
  • AppDelegate 객체는 앱 전체에 하나밖에 없으므로 모든 뷰컨에 접근할 수 있고, 앱이 종료되지 않는 이상 값을 유지할 수 있음

과정
1. AppDelegate.swift 파일에 변수(프로퍼티)를 추가
2. 값을 전달할 뷰컨에서 UIApplication.shared.delegate as? AppDelegate를 통해 AppDelegate를 호출하고, 객체를 다운캐스팅해주고, AppDelegate의 프로퍼티에 값을 넣는다

- 이와같이 앱 전체에 하나의 인스턴스만 있는 것을 싱글톤(Singleton)이라고 한다. 
그래서 인스턴스를 직접 생성할 수 없고 생성되어있는 인스턴스를 참조해야한다.
  1. 값을 받을 뷰컨에서 동일하게 AppDelegate를 호출하고 프로퍼티에 값을 받는다

UserDefaults 객체를 사용해서 값 주고받기

  • UserDefaults는 앱을 삭제하기 전까지는 저장된 값이 반영구적으로 유지된다.
  • 따라서 로그인 여부, 간단한 설정 정보등을 저장하는 경우가 많다.

과정
1. UserDefaults 객체 읽어오기
2. 인스턴스를 받아와서 set(_:forKey:)로 값 저장
3. 받을 뷰컨에서 인스턴스 불러와서 viewWillAppear에 값 불러넣기

profile
악으로 깡으로 버티기

0개의 댓글