iOS 在當(dāng)前控制器判斷是否是通過(guò)系統(tǒng)手勢(shì)返回上一個(gè)控制器
返回手勢(shì)
在日常開發(fā)中,往往我們會(huì)自定義返回按鈕,在返回到上一個(gè)控制器時(shí)做一些邏輯操作,比如一些數(shù)據(jù)回調(diào)等啤呼,但是又不想把手勢(shì)返回禁用掉,使用手勢(shì)返回時(shí)呢袱,自定義的一些數(shù)據(jù)處理又沒有提供方法來(lái)處理官扣,所以本篇文章會(huì)介紹如何判斷時(shí)通過(guò)手勢(shì)還是調(diào)用navigationController
的pop
方法返回上一個(gè)控制器。
開始介紹之前羞福,我們需要知道手勢(shì)返回的GestrueRecongnizer
@available(iOS 7.0, *)
open var interactivePopGestureRecognizer: UIGestureRecognizer? { get }
這個(gè)時(shí)UINavigationController
上的返回手勢(shì)
navigationController?.interactivePopGestureRecognizer?.delegate
當(dāng)設(shè)置這個(gè)代理時(shí)惕蹄,我們可以實(shí)現(xiàn)UIGestureRecognizerDelegate
代理方法,判斷手勢(shì)是否執(zhí)行
@available(iOS 3.2, *)
optional func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool
當(dāng)返回為true
時(shí)治专,控制器就可以響應(yīng)返回手勢(shì)
手勢(shì)判斷思路
首先卖陵,我們可以在執(zhí)行手勢(shì)的時(shí)候,判斷當(dāng)前手勢(shì)的狀態(tài)张峰,開始泪蔫,改變,結(jié)束等狀態(tài)喘批,所以我們可以給手勢(shì)添加一個(gè)事件撩荣,當(dāng)開始滑動(dòng)的時(shí)候,標(biāo)記當(dāng)前正在執(zhí)行手勢(shì)返回(isPoppedByInteractiveGesture
)谤祖,然后在控制器視圖消失的方法里面判斷是手勢(shì)返回婿滓,并且是pop
的時(shí)候老速,那么此時(shí)的返回就是手勢(shì)返回粥喜,而不是pop
方法返回。
這里有一個(gè)點(diǎn)橘券,就是如果手勢(shì)執(zhí)行到一半然后又取消的時(shí)候额湘,這個(gè)時(shí)候需要把isPoppedByInteractiveGesture
重置卿吐,表明取消了手勢(shì)返回,但是如果直接在手勢(shì)結(jié)束的狀態(tài)里面改變的時(shí)候锋华,在視圖消失時(shí)獲取到的isPoppedByInteractiveGesture
依然為false
嗡官,所以這里需要做一個(gè)延時(shí)操作,在一定的時(shí)間后將isPoppedByInteractiveGesture
重置為false
毯焕,這個(gè)時(shí)候視圖消失時(shí)獲取到的isPoppedByInteractiveGesture
就是我們想要的值衍腥,下面使用代碼來(lái)展示一下
class BaseViewController: UIViewController {
// 標(biāo)記手勢(shì)返回
var isPoppedByInteractiveGesture = false
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
navigationController?.interactivePopGestureRecognizer?.removeTarget(self, action: #selector(handlerGesture(_:)))
// isMovingFromParent這個(gè)表示從當(dāng)前控制器返回,手勢(shì)或者pop時(shí)都為true
if isMovingFromParent && isPoppedByInteractiveGesture {
// 添加手勢(shì)返回的數(shù)據(jù)處理操作
print("這個(gè)是手勢(shì)返回")
}
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// 視圖出現(xiàn)時(shí)纳猫,給手勢(shì)添加操作回調(diào)
navigationController?.interactivePopGestureRecognizer?.addTarget(self, action: #selector(handlerGesture(_:)))
navigationController?.interactivePopGestureRecognizer?.delegate = self
}
@objc func handlerGesture(_ gesture: UIGestureRecognizer) {
if gesture.state == .began { // 開始執(zhí)行時(shí)婆咸,先將標(biāo)記置為true
isPoppedByInteractiveGesture = true
}else if gesture.state == .ended || gesture.state == .cancelled || gesture.state == .failed { // 在結(jié)束的時(shí)候,給一個(gè)延時(shí)方法芜辕,重置為false
DispatchQueue.main.asyncAfter(deadline: .now() + 0.35) {[weak self] in
// 這里采用弱引用尚骄,防止控制器被延遲釋放
self?.changePoppedByInteractiveGesture()
}
}
}
@objc func changePoppedByInteractiveGesture() {
// 重置標(biāo)記
isPoppedByInteractiveGesture = false
}
// 在這里也可以判斷,
override func didMove(toParent parent: UIViewController?) {
super.didMove(toParent: parent)
// parent為nil時(shí)表示返回上一個(gè)控制器
if parent == nil && isPoppedByInteractiveGesture {
print("這個(gè)是手勢(shì)返回")
}
}
}
以上就是本篇的全部?jī)?nèi)容侵续,如果有更好的辦法倔丈,歡迎大家討論