自定义滑动返回手势的范围

2023-04-05  本文已影响0人  冰霜海胆
import UIKit

class ScreenPanGestureRecognizerViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        setupInterface()
    }

}

extension ScreenPanGestureRecognizerViewController {
    
    private func setupInterface() {
        setupGestureRecognizer()
    }
    
    private func setupGestureRecognizer() {
        
        guard UIDevice.current.isPhone else { return }

        // 以 iPhone SE 的 4 英寸为基准,大于这个尺寸宽度的才进行左侧边缘滑动返回手势的优化,扩大可触发的范围。
        guard UIDevice.current.detailedModel.size.width > UIDevice.current.phone("SE").size.width else { return }

        guard let target = navigationController?.interactivePopGestureRecognizer?.delegate else { return }

        let sel = Selector(("handleNavigationTransition:"))
        guard target.responds(to: sel) else { return }

        let panGR = UIPanGestureRecognizer(target: target, action: sel)
        panGR.delegate = self

        view.addGestureRecognizer(panGR)
        
        // 禁用系统自带的屏幕边缘滑动返回手势
        navigationController?.interactivePopGestureRecognizer?.isEnabled = false
        
//        navigationController?.interactivePopGestureRecognizer?.delegate = self
    }
    
}

extension ScreenPanGestureRecognizerViewController: UIGestureRecognizerDelegate {
    
    func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
                
        // 当前视图控制器为 “根控制器” 时,则不触发滑动返回手势事件。
        guard navigationController?.rootViewController != self else {
            return false
        }
        
        let location = gestureRecognizer.location(in: view)

        let width = view.bounds.width
        
        // 以 iPhone SE 的 4 英寸为基准,大于这个尺寸宽度的才进行左侧边缘滑动返回手势的优化,扩大可触发的范围。
        // 求出当前的差值,作为左侧滑动返回的可触发区域大小。
        let factor = width - UIDevice.current.phone("SE").size.width

        if location.x >= factor {
            return false
        }

        return true
    }
    
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        
        if children.count == 1 {
            return false
        }
        
        // 手势不能同时进行触发,防止例如 UITableView 上下滑动手势与滑动返回手势冲突。
        return false
    }

}

fileprivate extension UINavigationController {
    
    var rootViewController: UIViewController? {
        return viewControllers.first
    }
    
}
上一篇下一篇

猜你喜欢

热点阅读