addGestureRecognizer to rightBarButtonItem with customView

How I can add action to my rightBarButtonItem with customView?

Now I have code:

override func viewDidLoad() {
    super.viewDidLoad()
    configurePhotoProfile()
}

func configurePhotoProfile() {
    let imageView = UIImageView()
    let widthConstraint = imageView.widthAnchor.constraint(equalToConstant: 34)
    let heightConstraint = imageView.heightAnchor.constraint(equalToConstant: 34)
    heightConstraint.isActive = true
    widthConstraint.isActive = true
    imageView.kf.setImage(with: URL(string: channel?.recipientUrlImage ?? ""))
    imageView.backgroundColor = .clear
    imageView.layer.masksToBounds = true
    imageView.layer.cornerRadius = 17
    imageView.isUserInteractionEnabled = true
    imageView.addGestureRecognizer(UIGestureRecognizer(target: self, action: #selector(ChatsViewController.didTapImageButton(_:))))
    if UserDefaults.standard.integer(forKey: UserDefaultsKeys.selectedSegmentedControl) == 0 {
        self.navigationItem.rightBarButtonItem = UIBarButtonItem(customView: imageView)
    } else {
        self.navigationItem.rightBarButtonItem = nil
    }
}

@objc func didTapImageButton(_ sender: UIBarButtonItem) {
    print("tap")
}

But if I tap on barButtonItem I can't see my print("tap") in console. Where is my problem?

Upvotes: 0

Views: 372

Answers (5)

Maulik Pandya
Maulik Pandya

Reputation: 2230

I have a concern with your approach by getting an event using Gesture. It would be better to get an event using IBAction.

For that, you can add a custom view (UIView) in your NavigationItem and add UIImage and UIButton as a subview of that custom view.

Once you are done with the desired UI part you can create a IBAction for the added button.

Following image is an initial approach of your desired UI you can add subviews here

enter image description here

Upvotes: 0

Kishan Bhatiya
Kishan Bhatiya

Reputation: 2368

You are using base class for gesture recogniser, just use UITapGestureRecognizer in your code as updated below:

override func viewDidLoad() {
            super.viewDidLoad()
            configurePhotoProfile()
        }

        func configurePhotoProfile() {
            let imageView = UIImageView()
            imageView.translatesAutoresizingMaskIntoConstraints = false
            let widthConstraint = imageView.widthAnchor.constraint(equalToConstant: 34)
            let heightConstraint = 
            imageView.heightAnchor.constraint(equalToConstant: 34)
            heightConstraint.isActive = true
            widthConstraint.isActive = true
            imageView.kf.setImage(with: URL(string: channel?.recipientUrlImage ?? ""))
            imageView.backgroundColor = .clear
            imageView.layer.masksToBounds = true
            imageView.layer.cornerRadius = 17
            imageView.isUserInteractionEnabled = true
            let tap = UITapGestureRecognizer(target: self, action: #selector(ChatsViewController.didTapImageButton(_:)))
            tap.numberOfTapsRequired = 1
            imageView.addGestureRecognizer(tap)
            if UserDefaults.standard.integer(forKey: UserDefaultsKeys.selectedSegmentedControl) == 0 {
                self.navigationItem.rightBarButtonItem = UIBarButtonItem(customView: imageView)
            } else {
                self.navigationItem.rightBarButtonItem = nil
            }
        }

        @objc func didTapImageButton(_ sender: UIBarButtonItem) {
            print("tap")
        }

Upvotes: 0

Mahendra
Mahendra

Reputation: 8924

  • When you are setting constraints programatically on view which is also created programatically the you need to make do following...

    imageView.translatesAutoresizingMaskIntoConstraints = false
    
  • The above property need to make false to get work constraints programatically.

  • Another option is that you just specified the height and width of the constraints but you didn't specified the x position and y position. You need to specify (X,Y) position.

With ImageView

Using image view you can do the following.

func configurePhotoProfile() {
    let imageView = UIImageView(frame: .init(x: 0, y: 0, width: 34, height: 34))
    imageView.kf.setImage(with: URL(string: channel?.recipientUrlImage ?? ""))
    imageView.backgroundColor = .clear
    imageView.layer.masksToBounds = true
    imageView.layer.cornerRadius = 17
    imageView.isUserInteractionEnabled = true
    let tap = UITapGestureRecognizer(target: self, action: #selector(ChatsViewController.didTapImageButton(_:)))
    tap.numberOfTapsRequired = 1
    imageView.addGestureRecognizer(tap)
    if UserDefaults.standard.integer(forKey: UserDefaultsKeys.selectedSegmentedControl) == 0 {
        navigationItem.rightBarButtonItem = UIBarButtonItem(customView: imageView)
    } else {
        navigationItem.rightBarButtonItem = nil
    }
}

Instead of image you can add UIButton to bar button item(with custom view) like below.

let vw = UIButton(frame: .init(x: 0, y: 0, width: 34, height: 34))
vw.addTarget(self, action: #selector(ChatsViewController.didTapImageButton(_:)), for: .touchUpInside)

//set buttons other properties

let barButton = UIBarButtonItem(customView: vw)
navigationItem.rightBarButtonItem = barButton

Upvotes: 0

FE_Tech
FE_Tech

Reputation: 1750

I see that you are using base gesture recogniser class, You should use UITapGestureRecognizer instead.

Upvotes: 1

MBT
MBT

Reputation: 1391

Use UITapGestureRecognizer like below

let tap = UITapGestureRecognizer(target: self, action: #selector(ChatsViewController.didTapImageButton(_:)))
tap.numberOfTapsRequired = 1
imageView.addGestureRecognizer(tap)

Upvotes: 0

Related Questions