iOS:正确使用多视图的uipangeSturerogenter class /方法的正确方法



我需要为我所有视图重复使用pangesture方法,因为我不想在所有视图中重复这些方法。

所以,我想创建一个通用的uipangeSturerecognizer类以注册视图并调用委托方法以相应的视图。

实际上,我尝试过,但要遇到一些问题。因此,请指导我任何建议或参考。

好,这是我的代码

@objc protocol PanGestureRecognizerDelegate: UIGestureRecognizerDelegate{
    /// Called when the pan gesture recognizer starts.
    @objc optional func panGestureRecognizer(didStart gestureRecognizer: PanGestureRecognizer)
    /// Called when the pan gesture recognizer updates.
    @objc optional func panGestureRecognizer(didUpdate gestureRecognizer: PanGestureRecognizer)
    /// Called when the pan gesture recognizer cancels. A pan gesture recognizer may cancel if its translation or velocity in `initialDirection` is less than the value of `minimumTranslation` or `minimumVelocity`, respectively.
    @objc optional func panGestureRecognizer(didCancel gestureRecognizer: PanGestureRecognizer)
    /// Called when the pan gesture recognizer finishes. A pan gesture recognizer may finish if its translation and velocity in `initialDirection` are greater than or equal to the value of `minimumTranslation` or `minimumVelocity`, respectively.
    @objc optional func panGestureRecognizer(didFinish gestureRecognizer: PanGestureRecognizer)
}
class PanGestureRecognizer: UIPanGestureRecognizer {
    public enum Direction {
        /// The pan gesture recognizer's touches move upwards.
        case up
        /// The pan gesture recognizer's touches move leftwards.
        case left
        /// The pan gesture recognizer's touches move downwards.
        case down
        /// The pan gesture recognizer's touches move rightwards.
        case right
    }
    @IBInspectable open var minimumTranslation: CGFloat = 0.0
    /// Minimum velocity (in `initialDirection`) required for the gesture to finish. Defaults to `0.0`.
    @IBInspectable open var minimumVelocity: CGFloat = 0.0
    // MARK: Internal variables
    /// The current location in `view` when the pan gesture recognizer begins. Defaults to `nil`. Resets to `nil` when `reset()` is called.
    open fileprivate(set) var initialLocation: CGPoint?
    /// The current direction in `view` when the pan gesture recognizer begins. Defaults to `nil`. Resets to `nil` when `reset()` is called.
    open fileprivate(set) var initialDirection: Direction?
    // MARK: Delegation
    open override var delegate: UIGestureRecognizerDelegate? {
        didSet {
            self.addTarget(self, action: #selector(handlePan))
        }
    }
    internal var panDelegate: PanGestureRecognizerDelegate? {
        return delegate as? PanGestureRecognizerDelegate
    }
    // MARK: Initialization
    /// Initialize the pan gesture recognizer with no target or action set.
    public convenience init() {
        self.init(target: nil, action: nil)
    }
    // MARK: Overrides
    open override func reset() {
        super.reset()
        initialLocation = nil
        initialDirection = nil
    }
    // MARK: Actions
    internal func handlePan() {
        if (state == .began) {
            initialLocation = location
            initialDirection = direction
        }
        switch state {
        case .began:
            panDelegate?.panGestureRecognizer?(didStart: self)
        case .changed:
            panDelegate?.panGestureRecognizer?(didUpdate: self)
        case .cancelled:
            panDelegate?.panGestureRecognizer?(didCancel: self)
        case .ended where shouldCancel():
            panDelegate?.panGestureRecognizer?(didCancel: self)
        case .ended:
            panDelegate?.panGestureRecognizer?(didFinish: self)
        default:
            break
        }
        // set recognizer translation to zero
        self.setTranslation(CGPoint.zero, in: view)
    }
    // MARK: Cancellation
    fileprivate func shouldCancel() -> Bool {
        return translation() < minimumTranslation || velocity() < minimumVelocity
    }
}
// MARK: - Dynamic variables
extension PanGestureRecognizer {
    /// The pan gesture recognizer's current location in `view`, calculated using `location(in:)`. Returns `nil` if `view` is `nil`.
    public var location: CGPoint? {
        guard let view = view else {
            return nil
        }
        return location(in:view)
    }
    /// The pan gesture recognizer's current direction in `view`, calculated using `translation(in:)`. Returns `nil` if `view` is `nil`.
    public var direction: Direction? {
        guard let view = view else {
            return nil
        }
        let translation = self.translation(in: view)
        if (translation == .zero) {
            return nil
        } else if (fabs(translation.x) < fabs(translation.y)) {
            return translation.y > 0.0 ? .down : .up
        } else {
            return translation.x > 0.0 ? .right : .left
        }
    }
}
// MARK: - Directional helpers
extension PanGestureRecognizer {
    public func translation(inDirection direction: Direction? = nil) -> CGFloat {
        guard let direction = direction ?? initialDirection, let view = view else {
            return 0.0
        }
        return translation(in: view).magnitude(inDirection: direction)
    }
    public func velocity(in direction: Direction? = nil) -> CGFloat {
        guard let direction = direction ?? initialDirection, let view = view else {
            return 0.0
        }
        return velocity(in: view).magnitude(inDirection: direction)
    }
    public func translationPoint() -> CGPoint {
        return translation(in: view)
    }
    public func velocityPoint() -> CGPoint {
        return velocity(in: view)
    }
}

,我在情节板上添加了pangesture并将其分类。

@IBOutlet weak var panGestureRecognizer: PanGestureRecognizer!

如下

// MARK: View state
public func updateView() {
    let translation = self.panGestureRecognizer.translationPoint()
    //let velocity  = self.panGestureRecognizer.velocity(in: direction)
    let originY = self.view.frame.origin.y + translation.y
    let MIN :CGFloat = 0
    let MAX :CGFloat = (self.view.height - kMaxTranslation)
    if(originY <= MIN || originY >= MAX){
        return
    }
    self.view.frame.origin.y = originY
}

我正在调用下面的委托方法,

// MARK: - UIGestureRecognizerDelegate
extension MyViewController : UIGestureRecognizerDelegate {
    public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        guard let g = self.panGestureRecognizer else { return false }
        guard g.view is UIScrollView else { return false }
        return true
    }
    public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldBeRequiredToFailBy
        otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return false
    }
}
// MARK: - Pan gesture recognizer delegate
extension MyViewController: PanGestureRecognizerDelegate {
    @objc(panGestureRecognizerWithDidStart:) func panGestureRecognizer(didStart gestureRecognizer: PanGestureRecognizer) {
        updateView()
    }
    @objc(panGestureRecognizerWithDidUpdate:) func panGestureRecognizer(didUpdate gestureRecognizer: PanGestureRecognizer) {
        updateView()
    }
    @objc(panGestureRecognizerWithDidCancel:) func panGestureRecognizer(didCancel gestureRecognizer: PanGestureRecognizer) {
        updateView()
    }
    @objc(panGestureRecognizerWithDidFinish:) func panGestureRecognizer(didFinish gestureRecognizer: PanGestureRecognizer) {
        updateView()
    }
}

我在其中添加了一个带有pangesture的通用视图控制器,并将其扩展到我所有的ViewControllers。

现在,它工作正常。

相关内容

最新更新