Patrick Haertel
Patrick Haertel

Reputation: 329

How to make a UIBarButtonItem perform a function when pressed?

I am trying to make a custom back button using this code:

let back = UIImage(named: "header_backarrow")
let backView = UIImageView(image: back)
let backItem = UIBarButtonItem(customView: backView)
navigationItem.leftBarButtonItem = backItem

I want the navigation item to perform this code:

func dismissManual() {
    dismiss(animated: true, completion: nil)
}

I have tried many things like following this Stack Overflow post: Execute action when back bar button of UINavigationController is pressed

I have also tried making it a navigationItem.backBarButtonItem; however, nothing seems to work. Some things show the correct custom image, but do not work as a button; on the other hand, some work as a button, but do not show the correct image.

Does anybody know how I can show the correct image and make the item work as a button? Thanks.

Upvotes: 4

Views: 1835

Answers (4)

Praveen Gowlikar
Praveen Gowlikar

Reputation: 245

let barButtonItem = UIBarButtonItem(image: UIImage(named: "backImgs"),
                                            style: .plain,
                                            target: self,
                                            action: #selector(menuButtonTapped))

// Adding button to navigation bar (rightBarButtonItem or leftBarButtonItem)
self.navigationItem.rightBarButtonItem = barButtonItem

 // Private action
@objc fileprivate func menuButtonTapped() { // body method here }

Check out this, it may help Thanks.

Upvotes: 0

bobo pei
bobo pei

Reputation: 52

Do it as follows:

override func viewDidLoad() {
        super.viewDidLoad()

        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
    }

    @objc func dismissManual() {
        print("print----")
//        dismiss(animated: true, completion: nil)
    }

Add gesture to backView it will work! It's similiar to this question IOS - Swift - adding target and action to BarButtonItem's customView

Upvotes: 1

rmaddy
rmaddy

Reputation: 318794

You are creating your UIBarButtonItem incorrectly. You do not need the image view.

Do it as follows:

let back = UIImage(named: "header_backarrow")
let backItem = UIBarButtonItem(image: back, style: .plain, target: self, action: #selector(dismissManual))
navigationItem.leftBarButtonItem = backItem

@objc func dismissManual() {
    dismiss(animated: true, completion: nil)
}

Note that the function must be marked with @objc.

Depending on your image and how you want it displayed, you may need to create the image as follows:

let back = UIImage(named: "header_backarrow").withRenderingMode(.alwaysOriginal)

Another option is to create a UIButton with the image and setup to call your dismissManual function. Create the UIBarButtonItem with the button as the custom view.

But it's easier to create a standard UIBarButtonItem when all you have is a simple image or a simple string.

Upvotes: 0

llamacorn
llamacorn

Reputation: 551

Swift 4.1

The issue is that UIImage does not have tap recognition. You will have to add a tap gesture recognizer to your backView.

    lazy var singleTap: UITapGestureRecognizer = {
    let singleTap = UITapGestureRecognizer(target: self, action: #selector(tapDetected))
    singleTap.numberOfTapsRequired = 1
    return singleTap
}()

// Actions
@objc func tapDetected() {
    dismiss(animated: true, completion: nil)
}

If you show your code, with some screenshots I can give more help if this doesn't solve the issue.

Upvotes: 0

Related Questions