Ios 两个手势识别器之间的差异

Ios 两个手势识别器之间的差异,ios,swift,uigesturerecognizer,3dtouch,Ios,Swift,Uigesturerecognizer,3dtouch,我有两个手势识别器,一个是自定义3DTouch,另一个是单个UITapGestureRegonizer。我想这样做,如果你点击一次,它执行一个序列,如果你去麻烦的3dtouch之一,你会得到另一个视图。我尝试过很多方法,但都不起作用(我甚至尝试过使用计时器,但在开始时始终为0,无论其是否为3dtouch。)我的3dtouch自定义实现: //Without this import line, you'll get compiler errors when implementing your to

我有两个手势识别器,一个是自定义3DTouch,另一个是单个UITapGestureRegonizer。我想这样做,如果你点击一次,它执行一个序列,如果你去麻烦的3dtouch之一,你会得到另一个视图。我尝试过很多方法,但都不起作用(我甚至尝试过使用计时器,但在开始时始终为0,无论其是否为3dtouch。)我的3dtouch自定义实现:

//Without this import line, you'll get compiler errors when implementing your touch methods since they aren't part of the UIGestureRecognizer superclass
import UIKit.UIGestureRecognizerSubclass

//Since 3D Touch isn't available before iOS 9, we can use the availability APIs to ensure no one uses this class for earlier versions of the OS.
@available(iOS 9.0, *)
public class ForceTouchGestureRecognizer: UIGestureRecognizer {

    var timer = NSTimer()
    var counter = Double()

    //Since it also doesn't make sense to have our force variable as a settable property, I'm using a private instance variable to make our public force property read-only
    private var _force: CGFloat = 0.0

    //Because we don't know what the maximum force will always be for a UITouch, the force property here will be normalized to a value between 0.0 and 1.0.
    public var force: CGFloat { get { return _force } }
    public var maximumForce: CGFloat = 4.0

    func timerAction() {
        counter += 1
    }


    override public func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent) {
        super.touchesBegan(touches, withEvent: event)
        counter = 0

        timer = NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector: #selector(timerAction), userInfo: nil, repeats: true)
        print("COUNTER: \(counter)")

        normalizeForceAndFireEvent(.Began, touches: touches)
    }

    override public func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent) {
        super.touchesMoved(touches, withEvent: event)

        normalizeForceAndFireEvent(.Changed, touches: touches)
    }

    override public func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent) {
        super.touchesEnded(touches, withEvent: event)
        print("COUNTER: \(counter)")

        normalizeForceAndFireEvent(.Ended, touches: touches)
        timer.invalidate()

    }

    override public func touchesCancelled(touches: Set<UITouch>, withEvent event: UIEvent) {
        super.touchesCancelled(touches, withEvent: event)

        normalizeForceAndFireEvent(.Cancelled, touches: touches)
    }

    func normalizeForceAndFireEvent(state: UIGestureRecognizerState, touches: Set<UITouch>) {
        //Putting a guard statement here to make sure we don't fire off our target's selector event if a touch doesn't exist to begin with.
        guard let firstTouch = touches.first else {
            return
        }

        //Just in case the developer set a maximumForce that is higher than the touch's maximumPossibleForce, I'm setting the maximumForce to the lower of the two values.
        maximumForce = min(firstTouch.maximumPossibleForce, maximumForce)

        //Now that I have a proper maximumForce, I'm going to use that and normalize it so the developer can use a value between 0.0 and 1.0.
        _force = firstTouch.force / maximumForce

        //Our properties are now ready for inspection by the developer. By setting the UIGestureRecognizer's state property, the system will automatically send the target the selector message that this recognizer was initialized with.
        self.state = state
    }

    //This function is called automatically by UIGestureRecognizer when our state is set to .Ended. We want to use this function to reset our internal state.
    public override func reset() {
        super.reset()

        _force = 0.0
    }
}

如果我理解正确,您希望在同一UIView中添加两个不同的手势识别器。一个检测到正常抽头,另一个检测到用力抽头

对于正常点击,您可以使用UITapGestureRecognitor。对于强制点击,您必须创建自己的自定义手势识别器,该识别器监控触摸的力度,以确定力度是否足够高,是否符合强制点击手势的要求

以下是自定义强制点击手势识别器:

import UIKit.UIGestureRecognizerSubclass

@available(iOS 9.0, *)
public class ForceTapGestureRecognizer: UIGestureRecognizer {

    private var forceTapRecognized = false

    override public func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent) {
        super.touchesBegan(touches, withEvent: event)
        forceTapRecognized = false
    }

    override public func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent) {
        super.touchesMoved(touches, withEvent: event)
        guard let touch = touches.first else { return }
        if touch.force >= touch.maximumPossibleForce {
            forceTapRecognized = true
        }
    }

    override public func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent) {
        super.touchesEnded(touches, withEvent: event)
        state = forceTapRecognized ? .Ended : .Failed
    }
}

如果我理解正确,您希望在同一UIView中添加两个不同的手势识别器。一个检测到正常抽头,另一个检测到用力抽头

对于正常点击,您可以使用UITapGestureRecognitor。对于强制点击,您必须创建自己的自定义手势识别器,该识别器监控触摸的力度,以确定力度是否足够高,是否符合强制点击手势的要求

以下是自定义强制点击手势识别器:

import UIKit.UIGestureRecognizerSubclass

@available(iOS 9.0, *)
public class ForceTapGestureRecognizer: UIGestureRecognizer {

    private var forceTapRecognized = false

    override public func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent) {
        super.touchesBegan(touches, withEvent: event)
        forceTapRecognized = false
    }

    override public func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent) {
        super.touchesMoved(touches, withEvent: event)
        guard let touch = touches.first else { return }
        if touch.force >= touch.maximumPossibleForce {
            forceTapRecognized = true
        }
    }

    override public func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent) {
        super.touchesEnded(touches, withEvent: event)
        state = forceTapRecognized ? .Ended : .Failed
    }
}
class ViewController: UIViewController {

    let touchView = UIView(frame: CGRect(x: 100, y: 100, width: 100, height: 100))

    override func viewDidLoad() {
        super.viewDidLoad()

        let touchView = UIView()
        view.addSubview(touchView)

        let forceTapRecognizer = ForceTapGestureRecognizer(target: self, action: #selector(ViewController.didForceTap(_:)))
        let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(ViewController.didTap(_:)))
        tapRecognizer.requireGestureRecognizerToFail(forceTapRecognizer)
        touchView.addGestureRecognizer(forceTapRecognizer)
        touchView.addGestureRecognizer(tapRecognizer)
    }

    func didTap(recognizer: UITapGestureRecognizer) {
        print("tap")
    }

    func didForceTap(recognizer: ForceTapGestureRecognizer) {
        print("force tap")
    }
}