[Swift] interactivePopGestureRecognizer 버그?

앱 개발을 하다보면 UINavigationController 의 기존 Navigation Bar를 커스터마이징 하고 싶을 때가 있다. 하지만 기존 Navigation Bar의 제약등에 의해 원하는 UI를 구현할 수 없을 때, 그냥 숨겨버리고 자신만의 UIView로 대체하는 경우가 많다.

기본적으로 Navigation Bar를 숨기면 Back Swipe Gesture를 사용할 수 없다. 사용하기 위해선 Root View Controller에서 아래와 같은 코드를 추가해주어야한다.

self.navigationController?.interactivePopGestureRecognizer?.delegate = self

그런데.. 단순하게 저 코드 한 줄 추가하면 기능은 동작하지만, 이상한 버그가 생긴다.

위의 영상 처럼 Root View Controller에서 Back Swipe Gesture를 시도한 뒤 pushViewController 가 호출 되면 제대로 작동하지 않는다. 저 상태에선 UI 어느곳을 클릭해도 작동을 하지 않고 다시 Back Swipe Gesture를 시도해서 popViewController 를 해주어야 한다.

사용자의 입장에선 응답이 없으니 앱을 다시 껏다가 켜야하는 상황까지 오게된다… 혹시 이거 나만 그런건가 싶어서 실제 서비스중인 앱 몇 개를 받아봤는데 커스텀한 다른 앱들도 저렇게 되더라..(wavve 앱, 브랜디 앱(MY 페이지))

위의 버그는 아래와 같은 처리로 해결할 수 있다. rootViewController 에서 interactivePopGestureRecognizer 를 활성화 안하면 된다.

extension ViewController: UINavigationControllerDelegate {
    
    func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
        print("Child ViewControllers", navigationController.viewControllers.count)
        self.navigationController?.interactivePopGestureRecognizer?.isEnabled = navigationController.viewControllers.count > 1
    }
}

근데 이제 rootViewController에서 비활성화가 되었으니 Push된 ViewController에서 뒤로가기 제스쳐를 활성화 해주어야한다. 기본적으로 UIViewController 으로만 작성하진 않고 BaseViewController 등 새로운 공통 Class를 만들어서 viewWillAppear 에 제스쳐 활성화 코드를 넣어주자..