[UIKit] 스와이프로 페이지 뒤로가기

Charlie·2022년 6월 14일
0

UIKit

목록 보기
2/2

목차

  1. 방법 1 : Gesture를 인식하기
  2. 방법 2 : UINavigationController Extension
  3. 번외

SwiftUI의 NavigationView는 Swipe를 통한 뒤로가기 기능을 기본적으로 제공한다. 이는 NavigationView가 UIKit의 UINavigationController의 기능을 가지고 있기 때문인데, 다음과 같이 NavigationBar를 숨기게 되면 Swipe를 통한 뒤로가기 기능 또한 사용할 수 없게 된다.

.navigationBarHidden(true)


방법 1 : Gesture를 인식하기

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()
	}
})


방법 2 : UINavigationController Extension

아래와 같이 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
    }
}


Reference

Apple Developer Documentation - UINavigationController
Apple Developer Documentation - GestureState
Swift: Custom NavigationView에서 Swipe-back 가능하게 하기

profile
Hello

0개의 댓글