[swift] present, dismiss를 이용한 페이지 전환에서 viewWillAppear메서드가 호출이 안되는 문제 해결하기
1️⃣ 문제
-
[펼치기] 왜 viewWillAppear메서드를 썼을까
✹ 먼저 페이지1에서 페이지2를 열 수있으며 페이지2에서 입력한 값을 페이지1에 전달하는 상황이라고 칩시다.
✹ 페이지2에서 입력값을 받고 페이지1에 전달해줄때, 입력 후 페이지1의 새로운 인스턴트를 생성해서 여는 것은 매우 비효율적입니다. 대신에 페이지2를 없애고(메모리 해제) 페이지1를 다시 노출하는 방법을 이용합니다.
✹ 이 때 페이지2에서 새로 입력해준 값으로 페이지1의 프로퍼티를 업데이트 시켜주고 싶지만 viewdidload메서드는 처음에 로드될 때만 호출이 되기 때문에 페이지1에 되돌아가는 상황에서는 호출이 되지않습니다.
✹ 그 대신에 viewWillAppear메서드는 페이지가 노출이 될때마다 호출이 되기 때문에 잘 이용하면 페이지1의 프로퍼티를 업데이트 시켜줄 수 있습니다. - 하지만 present, dismiss를 이용한 페이지 전환에서 viewWillAppear메서드가 호출이 안되는 문제가 생겼습니다.
- 문제를 보기위해 다음과 같이 2개의 페이지로 이루어진 예시를 보겠습니다.
- 두개의 페이지는 각각
present
와dismiss
를 이용하여 페이지를 열고 닫습니다.
- 두번째 페이지에서 뒤로가기버튼을 눌러 첫번째 페이지로 되돌아가는데, 만약 viewWillAppear메서드가 호출된다면 첫번째 페이지의 제목이 “두번째 페이지에서 입력한 값”으로 바뀔 것 입니다.
- 아래 움짤을 보면 첫번째 페이지의 제목이 바뀌지 않습니다.
- 즉, viewWillAppear메서드가 호출되지 않았습니다.
- 애플 공식문서에서는 다음과 같이 말하고 있습니다. (대충
present
로 페이지를 팝업하고dismiss
로 헤제시 뷰컨트롤러에서 호출되지 않는다라는 내용)
< 애플공식문서 - viewWillAppear >
2️⃣ 해결방법
(1) fullscreen 이용
- 21년 기준
present
메소드는 기본적으로 페이지를 팝업의 형태로 열립니다. - iOS 13부터 modalPresentationStyle의 기본값이 fullScreen에서 automatic으로 바꼈다고 합니다.(레이어링(Layering)디자인을 둥근 상단 모양을 통해 구분되도록하여 뷰가 INteractively Dismissed 될 수 있게 하는 목적이라고 합니다.)
- 다음과 같이 스타일을 바꿔주면 풀스크린(fullscreen)으로 페이지가 열립니다.
- 풀스크린상태에서는 viewWillAppear메서드가 정상적으로 호출이 됨을 볼 수 있습니다.
- 노출 -> 비노출 -> 노출 의 상태변화가 일어나는 순간 viewWillAppear메서드가 호출됩니다.
팝업형태 로 두번째페이지를 열면 첫번째 페이지의 테두리 부분이 약간 노출되어 있는데, 이러한 작은노출도 페이지가 보여지고 있는 것으로 유지되기 때문에 상태변화가 일어나지 않고 viewWillAppear메서드가 호출되지 않는 것 같습니다.- 대신에
풀스크린 으로 첫번째 페이지를 완전히 가려주면 비노출로 상태가 변하기 때문에 다시 첫번째 페이지를 보여줬을 때 viewWillAppear메서드가 호출됨을 알 수 있습니다.
(2) Segue 이용시 fullscreen 적용법
- Storyboard에서는 Segue를 이용하여 간단하게 페이지 이동을 구현할 수 있습니다.
- 이때는 다음과 같이 직접 설정을 바꿔주면 됩니다.
- 여기까지 풀스크린으로 만드는 방법으로 viewWillAppear메서드 호출문제를 해결해 봤습니다.