[iOS] 앱의 화면전환이 항상 헷갈릴 때 보는 글




앱을 만들다보면, SingleView App에서 어느새 여러개의 화면전환이 필요한 순간이 오게됩니다. 그런데 화면 전환의 방법과 종류가 너무 많아서 어느 순간에 어떤 화면을 써야하는지 계속 찾계되어 정리하게 되었습니다.

  • 화면 전환할 때, 이전 코드를 복사해서 쓰고있는 사람
  • 다른 사람의 코드를 복사해서 화면전환을 하는 사람
  • 이것 저것 다 해보다가 내가 원하는 결과가 나온사람
  • 미래의 나

가 읽으면 좋을 것 같습니다.

화면전환

화면 전환이란 다른 화면이 등장하는 것을 말합니다. 버튼을 눌렀을 때 혹은 테이블 뷰나 컬렉션 뷰의 셀을 눌렀을 때 다른 화면이 나오는 경우이죠.

보통 많이 사용했던 방법을 나열 해보면 아래와 같습니다.

  1. viewController에서 다른 viewController를 present 해줍니다.
  2. NavigationController에 embed 시켜고 다른 viewController를 push 합니다.
  3. 스토리 보드에서 seque를 이용해서 control키를 누르고 드래그로 나타날 화면을 지정 해줍니다.

모달이나 전체화면과 같은 화면의 종류에 대해서는 이 글에서 다루지 않겠습니다. modalPresentationStyle에 대한 글을 나중에 정리하게 되면 추가 해놓겠습니다.

viewController에서 다른 viewController 부르기

viewController를 만드는 방법에는 저는 보통 2가지를 사용합니다. 코드로 만들거나, storyBoard에 뷰컨트롤러를 그립니다.

코드로 뷰 컨트롤러를 만들었을 때, present의 인자로 내가 만든 viewController의 인스턴스를 넘겨줍니다. 그러면 화면 전환이 일어납니다.

@IBAction func clickPresentByCodeButton(_ sender: Any) {
    let myViewController = MyViewController()
    self.present(myViewController, animated: true, completion: nil)
}

스토리 보드에 만들었을 때는, 스토리 보드에 그려진 뷰컨트롤러에 identifier를 지정해주고 해당 값을 이용해서 불러올 수 있습니다.

@IBAction func clickPresentButton(_ sender: Any) {
    guard let vcName = self.storyboard?.instantiateViewController(withIdentifier: "NewViewController") else { return }
    self.present(vcName, animated: true, completion: nil)
}

결국 뷰컨트롤러를 어떻게 만드느냐의 차이일 뿐, self(viewController)에서 다른 viewController를 persent 해주면 됩니다.

뷰컨트롤러에서 다른 뷰컨트롤러를 호출하면, 뒤로갈 수 있는 버튼이 제공되지 않습니다. NavigationController를 이용하는 이유 중 하나는, 상세 화면에서 뒤로가기를 쓰기 위해서 입니다. 네비게이션 컨트롤러에서 화면 전환을 하면 전환이 된다기 보다는, 화면위에 다른 화면을 올려놓는 느낌이기 때문입니다. 그렇기 때문에 이전화면으로 돌아 가기 쉽죠. 대신 좌측 상단에 뒤로가기 버튼도 생깁니다.

뷰 컨트러에서 화면 전환을 했던 것과 같은 방법으로, 네비게이션 컨트롤러에 embed된 뷰 컨트롤러의 화면 전환을 해줄 수 있습니다.

코드로 작성된 뷰 컨트롤러와, 스토리보드에 작성된 뷰 컨트롤러를 불러와서 화면전환 하는 부분은 윗 부분을 참고해주세요! 여기서는 네비게이션 컨트롤러에서 화면전환을 하면 뷰 뷰컨트롤러만 있을 때와 어떤 차이가있고 공통점이 있는지 보여드리겠습니다.

@IBAction func navigationPushButton(_ sender: Any) {
    guard let pushVC = self.storyboard?.instantiateViewController(withIdentifier: "OrangeViewController") else { return }
    self.navigationController?.pushViewController(pushVC, animated: true)
}

차이점이 보이시나요? 스토리 보드에 있는 뷰 컨트롤러를 인스턴스로 만든 다음에, self가 아닌, self.navigationController에서 pushViewController 해줍니다.

pushViewController 해주려면 navigationController에 viewController가 들어있어야겠죠?

스토리 보드에서 seque

화면 전환을 하는 방법중에는 가장 간단하고 생각합니다. 다만 이 방법을 쓰기 위해서는 storyBoard에 viewController들이 잘 그려져 있어야 한다는 전제조건이 필요합니다.

방법은 간단합니다. 스토리 보드상에서, 버튼을 클릭한 상태에서 control키를 눌러줍니다. 버튼을 다시 눌러주고, 드래그해서 불러 올 뷰 컨트롤러에 드랍 해줍니다. 그러면 뷰 컨트롤러사이에 segue 화살표가 생깁니다. 이 방법을 이용하면, 코드 한 줄 작성하지 않고 화면전환을 할 수 있습니다.

segue를 이용한 데이터 전달방법은 화면전환과는 다른 문제라 이 글에서 다루지는 않겠습니다.

정리

  • 스토리보드 없이
    • 네비게이션 컨틀롤러 없이
      • 코드로 만들어서
        • 뷰컨트롤러 인스턴스 생성
        • self.present
      • 스토리보드에 만들어서
        • self.storyboard?.instantiateViewController
        • self.present
    • 네비게이션 컨트롤러 있이
      • 코드로 만들어서
        • 뷰컨트롤러 인스턴스 생성
        • self.navigationController?.pushViewController
      • 스토리보드에 만들어서
        • self.storyboard?.instantiateViewController
        • self.navigationController?.pushViewController
  • 스토리보드 이용해서
    • segue를 사용해서

참고자료

에밀리의 블로그


댓글

이 블로그의 인기 게시물

[IOS] AppDelegate는 뭐하는 녀석이지?

[git] git의 upstream과 origin 헷갈리는 사람 손!

[git] Github 이슈 라벨(issue labels)