如何在 BarButtonitem 中检测长按

How to detect longpress in BarButtonitem

我在导航栏中有一个 UIBarButtonItem。当用户单击它时,它会弹出到另一个 viewController。 现在我希望当用户长按该按钮(导航栏按钮)时我想显示一条帮助消息。 我需要帮助来分别检测 onlick 事件和 longpress 事件。

在视图 didload 中试试这个:

let back = UIImage(named: "header_backarrow")
let backView = UIImageView(image: back)
backView.isUserInteractionEnabled = true
let tap = UITapGestureRecognizer(target: self, action: #selector(dismissManual))
backView.addGestureRecognizer(tap)
let backItem = UIBarButtonItem(customView: backView)
navigationItem.leftBarButtonItem = backItem

您应该创建一个按钮并将 UITapGestureRecognizer & UILongPressGestureRecognizer 设置为您的按钮

// Create a button
let yourButton = UIButton()
yourButton.backgroundColor = .red
yourButton.setTitle("long press", for: .normal)

// Create a tap gesture recognizer
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(didTap))

// Create a long gesture recognizer
let longGesture = UILongPressGestureRecognizer(target: self, action: #selector(long))

// You can set minimum duration of the press action 
longGesture.minimumPressDuration = 3 //The default duration is 0.5 seconds.

// Add your gestures to button
yourButton.addGestureRecognizer(longGesture)
yourButton.addGestureRecognizer(tapGesture)

navigationItem.leftBarButtonItem = UIBarButtonItem(customView: yourButton)
@objc private func didTap() {
    print("Did Tap")
}

@objc private func long() {
    // You can show the help message in here
    print("Long press")
}

在您的视图控制器的 viewDidAppear 中,您可以添加:

let gestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(myCalledFunction))
(myUIBarButton.value(forKey: "view") as? UIView)?.addGestureRecognizer(gestureRecognizer)

这很难,因为 UIBarButton 并没有真正暴露它的视图,所以你不能直接向它添加一个 gestureRecognizer。

不过,您可以使用 value(forKey:) 方法获取对其视图的引用,然后使用它。

不要在 viewDidLoad 中执行此操作,因为必须先创建视图才能使其工作。

所有其他答案都需要实施 UIBarButtonItem(customView:) 才能实现。然而,这可以通过任何 UIBarButtonItem 实例来实现,而无需实现您自己的手势识别器代码。

@IBAction 实际上可以传递包含 UIEvent 触发操作的第二个参数。例如,而不是定义 -

@objc func doSomething(sender: UIBarButtonItem) {
}

我们可以定义-

@objc func doSomething(sender: UIBarButtonItem, forEvent event: UIEvent) {
    guard let touch = event.allTouches?.first else { return }
    
    if touch.tapCount == 1 {
        // Handle tap
    } else if touch.tapCount == 0 {
        // Handle long press
    }
}

来源 : http://li366-68.members.linode.com/2016/09/07/detecting-long-presses-on-uibarbuttonitems.html

所以我发现 UIBarButton 不像长按那样 属性 所以我所做的就是让 UIButton 给它长按手势并将该 UIButton 作为 UIBarButtonItem 添加到导航栏中。

希望对遇到同样问题的其他人有所帮助。

        let btn = UIButton(frame: CGRect(x: 0, y: 0, width: 40, height: 40))
        btn.backgroundColor = .green
        
        let gesture = UILongPressGestureRecognizer(target: self, action: #selector(longpress))
        btn.addGestureRecognizer(gesture)
        
        let barbtn = UIBarButtonItem(customView: btn)
        self.navigationItem.rightBarButtonItem = barbtn

谢谢你:)