Search code examples
swiftuiviewuibuttonuinavigationbaruibarbuttonitem

Make whole UIView clickable in nav bar button?


I'm making a left bar button with a custom view (btnView). I want this view to be positioned on the edge of the screen, which Swift doesn't allow since it moves the bar button to the right if I try adding a view that's positioned further on the left. When I expand the frame to fit my UIView it simply shifts everything to fit the margin.

enter image description here < the limit is set at around 15 points from the edge.

Enabling isUserInteractionEnabled doesn't affect the clickability of the UIView, it still responds to that small area and not the leftmost edge.

Here's my button right now:

func addBackButton() {
        // position of btn view on navbar
        let btnView = UIView(frame: CGRect(x:-15.5, y:-6, width: 58.5, height: 44))
        // position of label in btn view
        let label = UILabel(frame: CGRect(x: 24.5, y: 13, width: 0, height: 0))
        label.font = UIFont.systemFont(ofSize: 17)
        label.textAlignment = .left
        label.textColor = .systemBlue
        label.text = "VET"
        label.sizeToFit()
        btnView.addSubview(label)
        
        let icon = UIImage(systemName: "chevron.left", withConfiguration: UIImage.SymbolConfiguration(pointSize: 23, weight: .medium))
        // convert UIImage to UIView
        let iconView = UIImageView(image: icon)
        // position of icon in btn view
        iconView.frame.origin.x = 5.5
        iconView.frame.origin.y = 12
        btnView.addSubview(iconView)

        // make small button to stick the view onto
        let backBtn = UIButton(type: .custom)
        backBtn.addTarget(self, action: #selector(goBack), for: .touchUpInside)
        backBtn.addSubview(btnView)
        
        // make button clickable behind btn view
        btnView.isUserInteractionEnabled = false

        // convert UIButton to UIBarButtonItem and add to navbar
        navigationItem.leftBarButtonItem = UIBarButtonItem(customView: backBtn)
    }

I also tried adding a second button onto btnView so it could be positioned correctly, but it was still unclickable for some reason, only the nav bar button area responded.

Is there a simpler way to achieve this? I want to avoid extra classes or extensions like I've seen in some of the threads, but I don't have any simpler options right now so I'm reconsidering.


Solution

  • Solution:

    I figured it out. You can add your view and button to your nav bar as Subviews instead of confining them to leftBarButton.

    1. I added the button over my view with:

           // add button over view to perform action
       let clickableBtn = UIButton(type: .custom)
       clickableBtn.frame = CGRect(x:0, y:0, width: 58.5, height: 44)
       clickableBtn.addTarget(self, action: #selector(goBack), for: .touchUpInside)
       btnView.addSubview(clickableBtn)
      
    2. Removed the isUserInteractionEnabled and the backBtn code

    3. And added the view to navbar with:

           // add btnView to navbar as subview
       navigationController?.navigationBar.addSubview(btnView)