present, performSegue

나이든별 / Oldstar·2022년 5월 4일
0

Think about Keywords

목록 보기
12/37

공부한 것

  • View Controller에서의 present(_ viewControllerToPresent: UIViewController, animated flag: Bool, completion: (() -> Void)? = nil))
  • performSegue(withIdentifier identifier: String, sender: Any?)

고민한 점 및 생각해본 점

  • present의 경우 이 메서드가 작동했을 때 가져올 뷰 컨트롤러, 애니메이션 여부, 이후에 처리해줄 completion handler를 파라미터로 받는다.
  • completion handler를 이후에 처리해준다는 것은, 화면 전환이 완전히 끝나고 나서 비동기 함수로써 클로저를 호출한다는 뜻이다.
  • 프로젝트를 수행하는 과정에서 이 메서드를 사용했을 경우에 나타났던 오류는, 지금 보고 있는 화면은 회색으로 비활성화되지만 정작 보고자 하는 화면은 나오지 않는 것이었다.
  • 그 이유는, 재고를 조절하는 뷰는 또 다른 Navigation Controller에 속해 있기 때문이다. present 메서드는, 내비게이션 컨트롤러를 무시하고 해당 뷰 컨트롤러를 modal하게 불러오는 함수. 따라서 어떤 형태로든 오류가 날 수 밖에 없었다.
    • 추가. 위의 말도 아주 틀린 건 아니지만, 좀 더 정확한 이유는 UIAlertController 또한 UIViewController를 상속하기 때문에 그런 것이다. present 메서드는 해당 함수를 불러온 뷰 컨트롤러 위에 모달하게 대상 뷰 컨트롤러를 불러오는 방식이다.
    • 띄워진 알림 창에서 '예'를 누르면 해당 알림 창은 사라진다. 그랬어야 하지만.. present 메서드 때문에, 실체가 없어진 UIAlertController 위에 모달하게 다음 뷰 컨트롤러가 불러와졌으니, 다음 뷰 컨트롤러는 불러와졌으되 기반이 된 뷰 컨트롤러, 여기서는 알림 창은, 사라져 있는 것이다.
    • 하지만 위에 어쨌든 겹쳐져 있는 뷰 컨트롤러가 있으니, 알림창의 존재는 완전히 소멸하지 못하고, 단지 화면 전체를 비활성화 시키기만 하는 것.
  • Navigation Controller는 스택의 형태로 뷰를 관리하며, pushpop으로 화면을 띄우고 닫는다. 애시당초 사용하는 메서드가 틀렸던 것.. 이라고 볼 수 있다.
  • 기본적으로 서로 다른 Navigation Controller를 사용했으므로, 이것도 좋은 결과를 내지 못했을 것이다. 하지만 의도적으로 이걸 써 보고, 코드를 망가뜨려 본 다음에 결과를 관찰하는 것도 좋을 것 같다.
  • present 함수를 처음 사용할 때 간과한 것이 두 가지가 있었던 것이다. 하나는 상술한 Navigation Controller, 또 하나는 segue.
  • 스토리보드 상에서 재고 관리 버튼을 눌렀을 때, 재고 조절 뷰에 임베드되어 있는 Navigation Controller로 우클릭 드래그를 통해 이어 줬었다. 막상 이 작업을 할 땐 신경썼으면서, 알림창에서 버튼을 눌렀을 때도 같은 원리로 화면이 넘어가야 한다는 것은 놓친 것.
  • 따라서, 이미 작업 과정에서 정해 준 segue를 작동시키면 원하는 대로 화면을 전환할 수 있으리라 생각했다.
  • performSegue(withIdentifier identifier: String, sender: Any?)는 뷰 컨트롤러에서 segue를 작동시킬 때 사용하는 메서드이다.
  • 여기서 잠깐! segue는 뷰 컨트롤러 사이의 연결 관계 및 화면 전환을 관리하는 역할을 한다.
  • 공식 문서에 따르면, 일반적인 경우 segue는 자동으로 작동되며, 별도의 함수를 필요로 하지 않는다. 다만, segue가 스토리보드에서 작동하는 경우가 아닐 경우, performSegue를 사용할 수 있다.
  • 또한 공식 문서에서 대표적으로 들고 있는 예시가, "you might call it from a custom action handler used in response to shake or accelerometer events".
  • 즉, 특정 이벤트에 반응하는, 직접 만든 액션 수행 클로저에서 불러서 segue를 작동시킬 수 있는 메서드라는 뜻이다. 이 경우가 바로 내가 사용하기로 한 경우.
  • 사용자가 '예' 버튼을 누르는 이벤트에 반응해, UIAlertAction에서 불러서 segue를 작동시켜야 하는 케이스. 딱 맞았다.
  • 또한 prepare(for segue: UIStoryboardSegue, sender: Any?) 메서드를 통해 segue를 작동시켜서 이동할 뷰 컨트롤러에 데이터를 넘겨줄 수도 있다. 이것도 유용하게 쓸 수 있을 듯..
  • sender 파라미터는 "The object that you want to use to initiate the segue"라고 한다. 즉 무엇으로 말미암아 segue를 작동시킬 것이냐! 하는 것.
    • 추가. sender 파라미터를 통해서 두 번째 뷰 컨트롤러에 데이터를 넘겨줄 수 있다! 이 경우 한 번의 검증이 필요하다.
    • 예를 들어 label.text에 넣어 줄 것을 보내고 싶은 경우, String 데이터를 넘겨받아야 적용할 수 있다. 또한 이 검증도 prepare 메서드 안에서 수행해줄 수 있다.

참조

https://developer.apple.com/documentation/uikit/uiviewcontroller/1621380-present (present)
https://developer.apple.com/documentation/uikit/uiviewcontroller/1621413-performsegue (performSegue)
https://developer.apple.com/documentation/uikit/uilabel (UILabel)
https://developer.apple.com/documentation/uikit/uialertcontroller (UIAlertController)

profile
함께 나아가고자 하는 사람

0개의 댓글