UITabBarController의 특정 탭에 Push Animation 적용하기

sanghoon Ahn·2021년 2월 12일
0

Daily Issue

목록 보기
2/10

Daily Issue #2

안녕하세요 dvHuni입니다 !! 데일리 이슈 두번째 포스팅 입니다~!!


무엇이 문제입니까?

오늘의 이슈 !! 두둥

바로 바로 UITabBarController의 특정 탭에 PushAnimation 적용하기입니다.

UITabBarController는 iOS에서 제공하는 TabBar를 가진 ViewController로써, 각 탭의 ViewController를 미리 만들어두고, Tab을 통해 화면을 전환합니다.

이때 화면 전환은 특별한 애니메이션 없이 이동하게 되는데요

특별한 상황이 생겼습니다! 🚨

탭의 특정 화면 전환을 할때 pushViewController 를 하는것처럼 화면이 들어오는 애니메이션을 적용해달라는 needs였습니다!😥

처음에는 어떻게 해결할까.. 고민끝에 TabBar를 커스텀해서 얹어볼까.. 생각했지만!!

경험자 선배님의 조언 덕에 해결책을 찾았습니다!

"Push Animation이 필요한 VC는 Push로 UITabBarController에 Push하되, TabBar의 인덱스는 해당 탭의 이전 인덱스 화면으로 되돌려놓기" 입니다!


앱의 화면 구조는 다음과 같습니다.

💥 앱 특성상 모든 Tab들이 navigation으로 이루어 져야 했기 때문에 모든 Tab들이 UINavigationController 입니다!!! 꼭 모든 Tab의 ViewController가 UINavigationController일 필요는 없습니다!

자, 그렇다면 UITabBarController의 기본 화면은 ViewController1이 되겠지요?

이제 ViewController3으로 화면 전환을 해 볼텐데, 아무 설정없이 3번째 탭을 클릭하게 되면 특별한 애니메이션 없이 화면전환이 이루어 집니다.

그러므로 BaseNavigationController에 ViewController3을 pushViewController 해 줍시다!

/*
 화면 구조 상 window의 Root ViewController가 UINavigationController이기 때문에 
 다음과 같이 작성하였습니다.
*/
guard let baseNavigationController = self.appDelegate?.window?.rootViewController as? UINavigationController else { return }
baseNavigationController.pushViewController(ViewController3()), animated: true)

그렇다면 이제 push 애니메이션을 가진채 ViewController3이 push 됩니다!!!🤩

하지만 아직 끝난게 아니죠, 탭을 누르면 화면전환이 되야되는데, 그러면 화면 전환이 되고 ViewController3이 push 되는건가? 어떻게 되는거지? 🤔


바로 다음과 같은 트릭을 사용합니다.

UITabBarController는 화면을 미리 만들어 두고 탭 시 화면전환을 한다고 했었죠 ?! 근데 ViewController3의 경우는 미리 만들어 TabBar의 ViewController로 적용할 필요가 없습니다!

탭을 누를 때 저희가 강제로 화면을 만들어서 push 해줄거니까요!!
(미리 만들어 둔 vc를 push해도 무방합니다 😇)

그러므로 TabBar의 화면을 지정할때, 다음과 같이 진행 해 봅시다!

/*
	편의상 tabBarItem은 빠져있습니다! 각 viewController에 UITabBarItem을 생성하여 지정해 주셔야
  tabBar에 아이콘, 타이틀이 보입니다!
*/
let viewController1 = FirstTabViewController()
let viewController2 = SecondTabViewController()
let viewController4 = FourthTabViewController()

tabBarController.setViewControllers([viewController1,
				     viewController2,
				     UIViewController()),
				     viewController4], animated: true)

TabBar의 세번째 화면이 빈 ViewController로 지정되어있죠 ?! 그렇다면 이제 어떻게 되느냐~

세번째 탭을 누를 경우, 빈 화면이 보여지고, 저희는 강제로 ViewController3을 push하게 됩니다!

이러면 조금 부자연스러운데 ...?? 하시는분들 !! 아직 안끝났습니다!

마지막으로 빈 화면에 진입 할 경우, tabBarController의 화면을 이전에 보고있던 화면으로 되돌려 주어야 부자연스럽지 않습니다!

예를들어, ViewController1 → ViewController3으로 이동 할 경우, ViewController3이 push되기 전에, tabBarController의 화면을 ViewController1의 화면으로 되돌려 놓습니다!!

어떻게 하느냐~ 두둥!

이전에 보고있던 탭의 인덱스를 저장할 변수를 하나 만들고 !! 탭 화면이 변할 때, 인덱스 값을 수정해 줍니다!

코드가 더 이해가 쉽겠죠?!

private var previousTabIndex: Int = 0

override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
    guard let items = tabBar.items else { return }
    for (index, tabBarItem) in items.enumerated() where tabBarItem == item {
	// viewController3의 index는 2입니다! 
        if index == 2 {
	    // 이전 인덱스로 화면 전환!
            selectedIndex = previousTabIndex 
						
	   // viewController3 push!
	   guard let baseNavigationController = self.appDelegate?.window?.rootViewController as? UINavigationController else { return }
	   baseNavigationController.pushViewController(ThirdViewController()), animated: true)
        } else {
	    // 그 외의 화면들은 인덱스 업데이트!
            previousTabIndex = index
        }
    }
}

이렇게 되면 화면이 push되기 전에 이전 인덱스의 화면으로 전환 후 push되기 때문에 ViewController3을 pop해도, 자연스러운 화면 전환이 이루어 집니다!

이상으로 UITabBarController의 특정 탭에 PushAnimation 적용하기 였습니다!


매일 개발하면서 생기는 수많은 크고작은 이슈들을 전부 포스팅 하고싶지만...
언제나 시간이라는 핑계를 두고 게을러지게 됩니다. 🤭

그래도 꾸준히 포스팅 하도록 노력해보겠습니다.

지적이나 질문은 언제나 환영입니다!!

읽어주셔서 감사합니다! 🙇‍♂️

profile
hello, iOS

2개의 댓글

comment-user-thumbnail
2021년 12월 6일

안녕하세요! 탭바 Pushanimation 기능구현 급하게 찾고있었는데, 작성 감사합니다! 그런데 해당 코드를 VC 어느부분에 작성해야하는지, 스토리보드로 구현할 때 저 코드를 사용해도 상관없는지 등 몇가지 여쭙고 싶은게 있는데, 'ha9764' 제 카톡아이디인데, 연락부탁드려도 될까요? ㅠㅠ

1개의 답글