我需要为我的所有视图重用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()
}
}
答案 0 :(得分:0)
我添加了带有手势的通用视图控制器,并将其扩展到我所有的视图控制器。
现在,它工作正常。