iOS 屏幕邊緣返回手勢(shì)與scrollView 滑動(dòng)沖突 和 全局返回手勢(shì)要點(diǎn):
右滑手勢(shì) 和 ScrollView滑動(dòng)手勢(shì)沖突.
- 自定義 ScrollView, 設(shè)置
self.panGestureRecognizer.delegate = self
- 實(shí)現(xiàn)代理方法:
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool
改代理方法大意為: 該方法返回YES時(shí),意味著所有相同類型的手勢(shì)都會(huì)得到處理守呜。 - 在改方法內(nèi)部, 給出一個(gè)
自定義距離
, 判斷在改距離內(nèi), 并且scrollView的contentOffset.x <= 0 (說明scrollView 是在沒有滑動(dòng)的情況下) 返回true: 表明在這個(gè)操作中, 允許多個(gè)手勢(shì)共存, 能夠處理多個(gè)手勢(shì)的響應(yīng). - 優(yōu)化的點(diǎn): 此時(shí)就在scrollView中, 既可以實(shí)現(xiàn)滑動(dòng), 又可以實(shí)現(xiàn)右滑返回手勢(shì). 但是此時(shí)右滑返回手勢(shì)和scrollView的滑動(dòng)同時(shí)生效, 右滑返回時(shí), 可以看到scrollView也在滑動(dòng). 這個(gè)時(shí)候就需要在scrollView的代理方法
func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool
中判斷, 如果是符合第三點(diǎn)時(shí) 返回false, 禁止scrollView的手勢(shì). 這個(gè)時(shí)候右滑返回, scrollView就不會(huì)跟著滑動(dòng)了.
全屏返回手勢(shì).
- 在
baseNavigationController
中, 將系統(tǒng)的interactivePopGestureRecognizer
移除, 并添加自定義的全屏返回手勢(shì).并設(shè)置其target action和 delegate
func addFullScreenGesture() {
let selector = NSSelectorFromString("handleNavigationTransition:")
fullScreenPopPanGesture = UIPanGestureRecognizer(target: self.interactivePopGestureRecognizer?.delegate, action: selector)
fullScreenPopPanGesture.delegate = self
view.addGestureRecognizer(fullScreenPopPanGesture)
interactivePopGestureRecognizer?.require(toFail: fullScreenPopPanGesture)
interactivePopGestureRecognizer?.isEnabled = false
}
handleNavigationTransition
是通過打印返回手勢(shì)拿到的返回響應(yīng)的action, 是私有API, 但是此API的使用并不會(huì)影響審核(經(jīng)網(wǎng)友測(cè)試發(fā)現(xiàn))
- 實(shí)現(xiàn)
UIGestureRecognizerDelegate
中的ShouldBegin方法, 在ShouldBegin方法中, 判斷手勢(shì), 和 手勢(shì)作用的開始點(diǎn).
func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
// print(gestureRecognizer)
guard self.viewControllers.count >= 1 else { return false }
if gestureRecognizer == fullScreenPopPanGesture {
let point = fullScreenPopPanGesture.translation(in: view)
if point.x > 0 {
return true
}
return false
}
return true
}
這樣子就替換掉了系統(tǒng)對(duì)pop的響應(yīng)方法, 系統(tǒng)響應(yīng)pop的方法只在屏幕邊緣響應(yīng), 現(xiàn)在替換成在整個(gè)屏幕point.x > 0 就響應(yīng).