EEYatHo 앱 깎는 이야기

Swift ) Swipe Back Detect 스와이프 뒤로가기 감지 - EEYatHo iOS 본문

iOS, Swift/Tip, Bug, Swift Error

Swift ) Swipe Back Detect 스와이프 뒤로가기 감지 - EEYatHo iOS

EEYatHo 2021. 7. 28. 12:52
반응형

swipe back 을 끄고, 키는 것은 interactivePopGestureRecognizer로 한다.

navigationController?.interactivePopGestureRecognizer?.isEnabled = true // false

 

 

하지만, back을 성공했는지 실패했는지 감지할 때는 한계가 있다.

@available(iOS 7.0, *)
open var interactivePopGestureRecognizer: UIGestureRecognizer? { get }

interactivePopGestureRecognizer는 그저 UIGestureRecognizer이기에,
얘를 아무리 들들 볶아도 화면 전환을 성공
했는지 실패했는지는 알 수 없다.

 

 

 

* 안되는 방법1 ) target을 이용한 방법 -> state가 began, changed, ended 만 나올 뿐, 성공실패는 모름.

override func viewDidLoad() {
    ...
    navigationController?.interactivePopGestureRecognizer?.addTarget(self, action: #selector(funcName))
}

@objc func funcName(_ recognizer: UIGestureRecognizer) {
    print("state: \(recognizer.state.rawValue)")
}

 

* 안되는 방법2 ) delegate를 이용한 방법 -> 위와 마찬가지. recognizer의 state를 얻는게 끝이다.

( 7개의 delegate함수들 중 유효한 함수를 찾지 못했다.. :(  )

override func viewDidLoad() {
    ...
    navigationController?.interactivePopGestureRecognizer?.delegate = self
}

func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
    ...
} // 외 6개 함수 더 존재

 

화면전환의 성공/실패는 당연히 UINavigationController나 UIViewController를 파고들어야 한다.

 

그러던 중, UINavigationController의 delegate를 이용해서 할 수 있는 방법을 찾아내었다.

override func viewDidLoad() {
    ...
    navigationController?.delegate = self
}

func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
    if let coordinator = navigationController.topViewController?.transitionCoordinator {
        coordinator.notifyWhenInteractionChanges({ (context) in
            print("Is cancelled: \(context.isCancelled)")
        })
    }
}

 

Swipe하면서 손을 땔 때,

 

back에 성공하면, context.isCancelled 가 false고,

현재화면을 유지하면, context.isCancelled 가 true로 분기가능하다.

 

Comments