Swift: 长按手势识别器 - 检测轻触和长按

50

我希望设置一个操作,如果手势是轻触,则以特定的方式对对象进行动画处理,但如果按压持续时间超过0.5秒,则执行其他操作。

现在,我只是连接了动画。 我不知道如何区分长按和轻触? 如何访问按压持续时间以实现上述功能?

 @IBAction func tapOrHold(sender: AnyObject) {
        UIView.animateKeyframesWithDuration(duration, delay: delay, options: options, animations: {

            UIView.addKeyframeWithRelativeStartTime(0, relativeDuration: 0, animations: {

                self.polyRotate.transform = CGAffineTransformMakeRotation(1/3 * CGFloat(M_PI * 2))
            })
            UIView.addKeyframeWithRelativeStartTime(0, relativeDuration: 0, animations: {
                self.polyRotate.transform = CGAffineTransformMakeRotation(2/3 * CGFloat(M_PI * 2))
            })
            UIView.addKeyframeWithRelativeStartTime(0, relativeDuration: 0, animations: {
                self.polyRotate.transform = CGAffineTransformMakeRotation(3/3 * CGFloat(M_PI * 2))
            })

            }, completion: { (Bool) in
                let vc : AnyObject! = self.storyboard?.instantiateViewControllerWithIdentifier("NextView")
                self.showViewController(vc as UIViewController, sender: vc)
        })
5个回答

104

定义两个IBActions,并为每个设置一个Gesture Recognizer。这样您就可以为每个手势执行两个不同的动作。

您可以在界面构建器中将每个Gesture Recognizer设置为不同的IBActions

@IBAction func tapped(sender: UITapGestureRecognizer)
{
    println("tapped")
    //Your animation code.
}

@IBAction func longPressed(sender: UILongPressGestureRecognizer)
{
    println("longpressed")
    //Different code
}

通过代码而非界面构建器

let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: "tapped:")
    self.view.addGestureRecognizer(tapGestureRecognizer)
    
let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: "longPressed:")
    self.view.addGestureRecognizer(longPressRecognizer)

func tapped(sender: UITapGestureRecognizer)
{
    println("tapped")
}

func longPressed(sender: UILongPressGestureRecognizer)
{
    println("longpressed")
}

Swift 5

let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(tapped))
self.view.addGestureRecognizer(tapGestureRecognizer)
    
let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(longPressed))
self.view.addGestureRecognizer(longPressRecognizer)
    
@objc func tapped(sender: UITapGestureRecognizer){
    print("tapped")
}

@objc func longPressed(sender: UILongPressGestureRecognizer) {
    print("longpressed")
}

7
长按时,好像无法正常使用,因为既触发了轻按,又触发了长按... - blue_zinc
你是否像上面的代码一样为每个手势识别器绑定了不同的IBActions?这对我有效。 - rakeshbs
4
感谢您也添加了代码版本,之前只找到使用界面生成器(Interface Builder)的答案,开始有些沮丧了。 - jolyonruss
我有一个表格,在cellForRowAtIndexPath方法中,我已经写了你建议的代码。我如何将rowId发送到操作函数?@rakeshbs - Dipen Gajjar
4
@blue_zinc 这个解决方案是:tapGestureRecognizer.require(toFail: longPressRecognizer)。 - 93sauu

28

适用于Swift2

let lpgr = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress))
lpgr.minimumPressDuration = 0.5
lpgr.delaysTouchesBegan = true
lpgr.delegate = self
self.featuredCouponColView.addGestureRecognizer(lpgr)

动作

//MARK: - UILongPressGestureRecognizer Action -
    func handleLongPress(gestureReconizer: UILongPressGestureRecognizer) {
        if gestureReconizer.state != UIGestureRecognizerState.Ended {
            //When lognpress is start or running
        }
        else {
            //When lognpress is finish
        }
    }

适用于Swift 4.2 / Swift 5

let lpgr = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress))
lpgr.minimumPressDuration = 0.5
lpgr.delaysTouchesBegan = true
lpgr.delegate = self
self.colVw.addGestureRecognizer(lpgr)

//MARK: - UILongPressGestureRecognizer Action -
    @objc func handleLongPress(gestureReconizer: UILongPressGestureRecognizer) {
        if gestureReconizer.state != UIGestureRecognizer.State.ended {
            //When lognpress is start or running
        }
        else {
            //When lognpress is finish
        }
    }

9
通过代码而不是界面构建器
// Global variables declaration
var longPressed = false
var selectedRow = 0



override func viewDidLoad() {
        super.viewDidLoad()  
        let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(ContactListTableViewController.handleLongPress(_:)))
        longPressGesture.minimumPressDuration = 1.0 // 1 second press
        longPressGesture.allowableMovement = 15 // 15 points
        longPressGesture.delegate = self
        self.tableView.addGestureRecognizer(longPressGesture)
    }

// Long tap work goes here !!
if (longPressed == true) {

       if(tableView.cellForRowAtIndexPath(indexPath)?.accessoryType == .Checkmark){
                tableView.cellForRowAtIndexPath(indexPath)?.accessoryType = .None
                self.selectedRow -= 1

                if(self.selectedRow == 0){
                    self.longPressed = false
                }

            } else {
                self.selectedRow += 1
                tableView.cellForRowAtIndexPath(indexPath)?.accessoryType = .Checkmark
            }

        } else if(self.selectedRow == 0) {
          // Single tape work goes here !!
        }

但唯一的问题是长按手势会运行两次。如果您找到了任何解决方案,请在下面评论!

9
检查识别器状态:if (gestureRecognizer.state == UIGestureRecognizerStateBegan) - Arvis
@Arvis,你会把这个if语句放在哪里,以防止长按手势函数被多次执行? - PlateReverb
3
@PlateReverb在选择器操作函数中。 - Arvis

0

使用界面构建器的Swift 5

对于普通的点击,您可以从按钮中简单地创建一个touch up inside操作。

对于长按,创建一个按钮的输出口,创建触摸手势识别器并将其设置为按钮,然后创建选择器方法来执行长按任务。

@IBOutlet var myButton: UIButton!

override func viewDidLoad() {
    super.viewDidLoad()
    
    let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(addToListButtonLongPress(_:)))
    longPressRecognizer.numberOfTouchesRequired = 1
    longPressRecognizer.allowableMovement = 10
    longPressRecognizer.minimumPressDuration = 0.5
    myButton.addGestureRecognizer(longPressRecognizer)
}

// Connected to myButton in interface builder.
@IBAction func myButtonTapped(_ sender: UIButton) {
    print("button tapped")
}

@objc func myButtonLongPressed(_ sender: UILongPressGestureRecognizer) {
    print("button long pressed")
}

-1
iOS的tapGesture和longPressGesture 在这个例子中,每次改变或结束一个动作时,onLongPress()的内容不会被执行。
let tap = UITapGestureRecognizer(target: self, action: #selector(self.onClick))
self.myView.addGestureRecognizer(tap)

let longPress = UILongPressGestureRecognizer(target: self, action: #selector(self.onLongPress))
longPress.minimumPressDuration = 0.5
self.myView.addGestureRecognizer(longPress)


@objc func onClick() {
    //logic
}

@objc func onLongPress(sender: UILongPressGestureRecognizer) {
    guard sender.state == .began else { return }
    //logic
}   

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接