목차
SwiftUI의 NavigationView는 Swipe를 통한 뒤로가기 기능을 기본적으로 제공한다. 이는 NavigationView가 UIKit의 UINavigationController의 기능을 가지고 있기 때문인데, 다음과 같이 NavigationBar를 숨기게 되면 Swipe를 통한 뒤로가기 기능 또한 사용할 수 없게 된다.
.navigationBarHidden(true)
GestureState 변수를 선언하고 View에서 .gesture( )를 통해 Gesture를 인식하여 뒤로가게 하는 방법이 있다.
@Environment(\.presentationMode) var mode: Binding<PresentationMode>
@GestureState private var dragOffset = false
VStack {
// Contents
}
.gesture(DragGesture().updating($dragOffset) { (value, state, transaction) in
if (value.startLocation.x < 30 && value.translation.width > 100) {
self.mode.wrappedValue.dismiss()
}
})
아래와 같이 UINavigationController를 직접 수정하여 PopGesture를 인식해 전달하는 delegate를 해당 NavigationView에 연결시켜주면 된다.
extension UINavigationController: ObservableObject, UIGestureRecognizerDelegate {
override open func viewDidLoad() {
super.viewDidLoad()
interactivePopGestureRecognizer?.delegate = self
}
public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
return viewControllers.count > 1
}
}
gestureRecognizerShouldBegin 함수는 NavigationStack에 View가 하나보다 많을 때 Gesture의 인식을 시작하도록 한다.
위 코드를 통해 NavigationBar를 숨기면서 상실했던 기본으로 제공하는 Swipe를 통한 뒤로가기 기능을 다시 사용할 수 있다.
NavigationBar를 커스텀하여 사용하게 되는 경우에는 계속해서 아래와 같은 코드를 View마다 붙여줘야 하는 번거로움이 있다.
.navigationBarTitle("")
.navigationBarHidden(true)
View에서 UINavigationController를 호출하여 설정을 할 때는 다음과 같이 작성을 하면 된다.
navigationController?.navigationBar.isHidden = true
하지만 앞선 상황과 같이 UINavigationController의 extension을 작성하는 상황에서는 다음과 같이 한줄의 코드만 viewDidLoad( )에 추가해주면 된다.
navigationBar.isHidden = true
따라서 아래의 코드를 자주 사용하게 될 것 같다.
extension UINavigationController: ObservableObject, UIGestureRecognizerDelegate {
override open func viewDidLoad() {
super.viewDidLoad()
navigationBar.isHidden = true
interactivePopGestureRecognizer?.delegate = self
}
public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
return viewControllers.count > 1
}
}
Apple Developer Documentation - UINavigationController
Apple Developer Documentation - GestureState
Swift: Custom NavigationView에서 Swipe-back 가능하게 하기