[SwiftUI]커스텀 백버튼 백 제스처 시 화면 멈춤 이슈 해결

Youngkyu·2021년 12월 20일
0
post-thumbnail

XCode : 13.2.1
타겟 버전 : 14.0 이후
시뮬레이터 버전 : 15.2

개요

프로젝트를 진행하면서 디자이너님의 요구사항에 맞게 백버튼을 커스텀해야 할 일이 생겼다. 그러나 SwiftUI에선 아직 NavigationBar 백버튼의 디자인을 바꿀 수 있는 옵션을 제공하지 않아 커스텀하여 사용하기로 했다. 그러나 커스텀 백버튼을 만들고 hidden 옵션을 주면 백 제스처가 동작하지 않았고

.navigationBarHidden(true)

찾다보니 UINavigationController를 직접 수정하면 해결 할 수 있다고 했다.

interactivePopGestureRecognizer?.delegate = self

그러나 Navigation Stack에 뷰가 하나밖에 없는데 뷰를 pop 해버리면 안되기때문에 view가 2개 이상일 경우에만 동작하도록 처리가 필요했다.

문제된 기존 코드 (따라하지 마세요ㅜㅜ)

extension UINavigationController : UINavigationControllerDelegate {
    open override func viewDidLoad() {
        super.viewDidLoad()
        interactivePopGestureRecognizer?.delegate = nil
    }
    
    public func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
        self.interactivePopGestureRecognizer?.isEnabled = self.viewControllers.count > 1
    }
    
}

당시엔 시험기간이기도 하고 풀리지 않을 것 같은 버그에 뇌정지가 와서 한참동안 내려놓고 있다가 종강하고 다시봤더니 이게 뭐람
천천히 뇌버깅 해보니 네비게이션 뷰가 viewDidLoad() 될때마다 해당 네비게이션 뷰의 delegate를 날려버리니까 아무리 isEnabled해도 안됐던 것이다.🤯

self.interactivePopGestureRecognizer? // 여기서 이미 nil

기존 버그 현상

수정된 코드

extension UINavigationController : UINavigationControllerDelegate, UIGestureRecognizerDelegate {
    open override func viewDidLoad() {
        super.viewDidLoad()
        interactivePopGestureRecognizer?.delegate = self
    }

    // MARK :  Navigation Stack에 쌓인 뷰가 1개를 초과해야 제스처가 동작 하도록
    public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
            return viewControllers.count > 1
    }

}

그렇게 다른 레퍼런스를 통해 gestureRecognizerShouldBegin을 알게되어 Navigation Stack 에 쌓인 뷰가 1개를 넘을때만 제스처가 동작하도록 바꿨더니 해결되었다! 너무 후련 😞

버그 수정


초기화면에서 백 제스처 시 Navigation Stack에 View가 하나밖에 없어 제스처가 동작하지 않는 모습

참고링크

https://medium.com/hcleedev/swift-custom-navigationview%EC%97%90%EC%84%9C-swipe-back-%EA%B0%80%EB%8A%A5%ED%95%98%EA%B2%8C-%ED%95%98%EA%B8%B0-c3c519c59bcb

profile
iOS를 공부하고 있는 대학생입니다.

0개의 댓글