1

I have a UIBarButtonItem in navigation bar. When a user clicks it, it pops to another viewController. Now i want that when user long-press on that button (navigation bar button) I want to show a help message. I want help to detect the onlick event and longpress event separately.

The Tom
  • 2,790
  • 6
  • 29
  • 33
Shivam Parmar
  • 1,520
  • 11
  • 27
  • How did you added `BarButtonItem` to your `NavigationBar`? – emrcftci Mar 09 '20 at 07:42
  • Did you read this old thread ? https://stackoverflow.com/questions/2655630/how-can-you-add-a-uigesturerecognizer-to-a-uibarbuttonitem-as-in-the-common-undo. problem is that barButton are not UIButtons, so you need some workaround. – claude31 Mar 09 '20 at 08:10
  • you can create custom navBar instead of default one, and handle tap actions by using tapGestures. – Mudassir Asghar Mar 09 '20 at 13:13

5 Answers5

1

try this in view 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
emrcftci
  • 3,355
  • 3
  • 21
  • 35
Lokesh gupta
  • 94
  • 10
1

You should create a button and set UITapGestureRecognizer & UILongPressGestureRecognizer to your button

// 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")
}
emrcftci
  • 3,355
  • 3
  • 21
  • 35
1

In the viewDidAppear of your view controller you can add this :

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

This is difficult because UIBarButton doesn't really expose its view and so you cannot directly add a gestureRecognizer to it.

You can however get a reference to its view by using the value(forKey:) method and then play with it.

Do not do this in the viewDidLoad as it is necessary for the view to have already been created in order for this to work.

The Tom
  • 2,790
  • 6
  • 29
  • 33
1

All of the other answers require implementing a UIBarButtonItem(customView:) to achieve this. However this can be implemented with any UIBarButtonItem instance without implementing your own gesture recognizer code.

An @IBAction can actually be passed a second parameter containing the UIEvent triggering the action. For example, instead of defining -

@objc func doSomething(sender: UIBarButtonItem) {
}

We can define -

@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
    }
}

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

Tarun Tyagi
  • 9,364
  • 2
  • 17
  • 30
1

so I found that UIBarButton has not property like longpress so all I do is take a UIButton give it longpress gesture and add that UIButton in navigation bar as UIBarButtonItem.

I hope it will helpful for someone else who is facing same problem.

        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

thank you :)

Shivam Parmar
  • 1,520
  • 11
  • 27
  • Unfortunately doing so you can't use system buttons like the share action button. Look at the solution posted by The Tom. That's what is working for me. – kaharoth Sep 21 '22 at 10:20