IOS/IOS 기본

끄적끄적2

알로하리미 2021. 5. 4. 09:39
728x90

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

값전달의 두가지 개념 

- 진접전달과 공유방식이 있다.

1. 직접전달 

   값을 저장할 필요가 없는 화면 전환에서 사용

   화면이 전환될때 데이터가 함께 전달되거나 화면이 전환되기 전에 데이터가 미리 전달 되므로 전달 과정에서 값이 누락될 염려가 없다는 장점 이 있다. 이방식은 화면전환과 값전달이 함께 이루어진다. 동기 방식이라고도 한다.

값을 전달 받는 쪽의 뷰 컨트롤러가 전달받을 값의 명세를 모두 파악하고 이를 대입할 변수를 미리 생성해 두어야 한다는 다점이 있다. 이를 위해 보내는 뷰 컨트롤러에서는 받는 뷰 컨트롤러에 대한 정보를 미리 확인할 수 있어야한다.

1. vc1에서 vc2로 전달할 값준비
2. vc2에서 값을 대입받을 프로퍼티 정의
3. vc1에서 vc2의 인스턴스를 직접생성(프레젠테이션, 내비게이션 컨트롤러 등)하거나, 이미 생성되어 있는 인스턴스의 참조(세그웨이 destination, source 등) 를 읽어옴.
4. vc1에서는 2번에서 정의한 vc2인스턴스의 프로퍼티에 값을 대입
5. vc1에서 vc2로 화면 전환

2. 공유방식 : 공통저장소를 이용하는 방법 

  지속적으로 값을 저장할 필요가 잇는 화면전환에서 이루어짐. 로그인정보 같은것들. 로그인 성공했을때 로그인정보를 등록해놓고 화면을 전환.

저장소에 데이터가 저장되는 시점과 호면 전환 시점이 일치하지 않으면 값 전달이 제대로 안 될수 있다.

화면이 전환되었음에도 값을 전달 받지 못하는 경우가 생기므로 이에대한 처리가 필요

화면 전환과 값의 전달이 따로 이루어진다는 점에서 편의상 비동기 방식이라고도 한다.

보내는쪽과 받는쪽 모두 저장소의 위치를 사전에 공유하고 있어야 한다. 

 

- 액션 메소드를 정의할 때에는 매개변수을 두가지 방식중에서 선택적으로 지정할수 있다. 범용타입인 Any타입과 UIxxx으로 시작하는 개별타입이다. Any타입으로 선언하면 하나의 액션 메소드를 서로 다른타입의 컨트롤들이 공용으로 사용할수 있어 편리하지만 막상 해당 인자값을 사용해야 할 때에는 다시 하위 타입으로 캐스팅해주어ㅑ 하기 때문에 구처장스러울수 있다. 반면 개별 타입으로 선언해 두면 해당 메소든느 이에 맞는 타입의 컨트롤만 호출할수 있어 제한적이지만, 컨트롤의 속성을 제어하거나 읽어 들여야 할 경우엔 캐스팅 할 필요 없이 바로 사용할 수 있습니다.

- 액션메소드 매개변수 타입 Any 선택 : 

1. 서로 다른 타입의 컨트롤리 동일한 액셔 메소드를 호출하게끔 처리하고 싶을때
2. 액션 메소드를 호출한 컨트롤의 정보가 필요 없을때
3. 개별 타입을 반드시 사용해야 하는 경우를 제외한 나머지 모든 경우

- 액션메소드 개별 타입선택 : 액션 메소드를 호출한 컨트롤의 속성값이 필요하거나, 이를 제어해야할때

- 아울렛 변수는 외부에서 값을 직접 대입할 수 없는 변수 입니다. 대신 시스템에 의해 값이 주입된다. 게다가 아울렛 변수는 외부 객체에서 직접 참조 할수 없도록 제한되어있다. 다른 뷰컨트롤러에서 바로 값을 대입 할 수 없으므로 , 값을 대입할 프로퍼티를 따로 정의해야한다.

- viewDidLoad() 메소드는 화면이 메모리에 로드되고 난 시점에 호출된다. 즉 , 무언가를 준비(셋팅)할때

- 애플의 UI지침에 따르면 내비게이션 바를 사용하는 경우 액션 처리 버튼은 가급적 내비게이션 바에 배치하는 것이 좋다.

- 일반 버튼을 네비게이션 바로 옮기는 과정에서 연결정보가 끊어진다. 이는 일반버튼이 bar button item으로 변경되었기 때문이다. 연결정보를 다시 연결해줘야한다.

- 세그웨이로 값전달시에 prepare(for segue:sender:) 전처리 메소드를 구현하여 값을 전달할 수 있다. 대상의 인스턴스를 직접 생성하여 전달하면안된다. 이미 세그웨이(segue)에 destination(대상)으로 생성이 되어있기때문이다. UIViewController를 반환하기때문에 대상viewController의 프로퍼티를 사용하기 위해서 다운캐스팅 해줘야한다.

- 이전화면 으로 값 전달하기

- 다음화면으로 값전달
1. 값을 받을 새로운 화면을 스토리보드에추가하고, 여기에 맞는 클래스 파일을 작성하여 둘 사이를 연결한다.(vc2)
2. 스위프트 코드를 사용하여 vc2에 대한 인스턴스 참조를 얻어오거나, 인스턴스 참조가 없는 경우 인스턴스를 생성한다.
3. 전달하고자 하는 값을 인스턴스의 적절한 프로퍼티에 대입한다 이때 프로퍼티들은 미리 정의 되어있어야한다.
4. 화면 전환을 한다.

- 이전화면으로 값전달
vc2->vc1으로 값을 전달할때에는 vc1의 인스턴스가 초기화되지 않기때문에 viewDidLoad()메소드가 호출되지 않습니다. 대신 화면이 새롭게 그려질때마다 호출되는 viewWillAppear(_:) 메소드가 호출되기에 여기에 코드작성을해야한다.

일반적으로 vc1->vc2로 전달하는 값은 휘발성 값이 대부분이라 값을 저장해둘 필요없이 두개의 뷰 컨트롤러 사이에서만 값을 주고받으면 끝입니다.
반면에 vc2->vc1 으로 전달하는 값은 대체로 반영구적으로 저장해야 하는 값인 경우가 많습니다. 단순히 뷰 컨트롤러 사이에서만 값을 주고받는다면, 값을 받은 뷰 컨트롤러(vc2)가 또 다른 화면으로 전환될 경우 전달된 값이 소실될 수 잇습니다(왜냐면 뒤로돌아갈시에 vc2인스턴스가 해제 되기 때문이다.). 그러므로 값의 성격을 고려하여 전달방식을 택해야합니다(소실되도 상관없으면 동기방식-직접전달 하면된다.)

- ios13부터 뷰 모달 컨트롤러엔느 모달 프레젠테이션스탕일로 UIModalPresentationOverFullScreen이 있으므로 이전뷰가 사라지지 않으므로 viewWill ~ viewDid 관련 함수가 호출 되지 않는다. 스타일을 .fullscreen으로 하면 viewWill viewDid가 동작 가능하다. 기본으로 .pageSheet으로 되어있으면 이전뷰가 살아있기에 동작하지 않는다.
ios13 라이프 사이클을 잘 알아봐야한다.

- 데이터를 appdelegate클래스에 두면 데이터는 앱이 종료되기 직전까지만 유지된다.

- 데이터를 반영구적으로 저장시에는  UserDefaults - 간단한 데이터 저장(로그인정보등), Core Data객체 - 복잡한 데이터 저장 을 사용해야한다.

- AppDelegate 클래스를 대체할수 있도록 다른 클래스를 만들 수 있는데
1. UIResponse클래스를 상속받아야하고
2. UIApplicationDelegate프로토콜 구현을 선언해야하고
3. @UIApplicationMain 어노테이션을 붙여줘야합니다.( 하나의앱에 하나의 어노테이션만 가능 )

- UserDefaults 객체에서 값을 일어오는 메소드 중 String 타입의 메소드만 반환값이 옵셔널 타입이다.
UserDefaults 인스턴스에서 .value(forkey:)  , .object(forKey:) 는 Any타입을 반환하기에 캐스팅 as? 해줘야한다.