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가 하나밖에 없어 제스처가 동작하지 않는 모습