UIBarButtonItem created with custom view rendered in wrong location

I'm creating a UIBarButtonItem using a custom view. I won't know the exact width of the custom view in advance so I'm attempting to do the layout using constraints.


The issue is that the custom view is rendered at the top left of the screen (position 0,0) instead of in it's expected navigation item location.


Here's some simplified code that reproduces the issue:

class ViewConstroller: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
  
        let customView = UIView()
        customView.translatesAutoresizingMaskIntoConstraints = false
        customView.addConstraint(NSLayoutConstraint(item: customView, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 40.0))
        customView.addConstraint(NSLayoutConstraint(item: customView, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 40.0))
        customView.backgroundColor = UIColor(white: 0.5, alpha: 1.0)

        navigationItem.rightBarButtonItem = UIBarButtonItem(customView: customView)
   }
}


Interestingly, if you create a custom view from a frame, then it's rendered in the correct location. Here's some code that will create a view in the correct place:

class ViewConstroller: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
  
        let customView = UIView(frame: CGRectMake(0, 0, 40, 40))
        customView.backgroundColor = UIColor(white: 0.5, alpha: 1.0)
       
        navigationItem.rightBarButtonItem = UIBarButtonItem(customView: customView)
   }
}


Does anyone have an idea what I might be doing wrong in the first example?

Replies

Hi Tebs,

Try adding a negative spacer and change the method addConstraint to addTarget. For example:


var button: UIButton = UIButton()

button.setImage(UIImage(named: "yourButtonImage"), forState: .Normal)

button.frame = CGRectMake(0, 0, 40, 40)

button.addTarget(self, action: "yourFunction:", forControlEvents: .TouchUpInside)

var leftBarButtonItem:UIBarButtonItem = UIBarButtonItem()

leftBarButtonItem.customView = button

var negativeSpacer:UIBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FixedSpace, target: nil, action: nil)

negativeSpacer.width = -5; /

self.navigationItem.leftBarButtonItems = [negativeSpacer,leftBarButtonItem]