Search code examples
iosuikituinavigationcontrolleruinavigationbaruinavigationitem

UiNavigationController - title in navigation bar is off-center when right side has 2 buttons


I'm using a UINvagigationController for my app, with every page setting their own title and left and right buttons. Worked perfectly until I needed two buttons to the right. Just setting them as bar button items throws the title off-center, and the space between them is way bigger then expected: enter image description here

This is how I set up those buttons to the right:

    let item1 = UIBarButtonItem(customView: self.btnGoToScan)
    let item2 = UIBarButtonItem(customView: self.btnExportImage)
    self.navigationItem.setRightBarButtonItems([item1, item2], animated: false)

I have tried setting the width of those items, as well as adding fixed space of negative width between them - changes nothing:

let item1 = UIBarButtonItem(customView: self.btnGoToScan)
    item1.width = 24
    let item2 = UIBarButtonItem(customView: self.btnExportImage)
    item2.width = 24
    let negativeSpace = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil)
    negativeSpace.width = -16
    self.navigationItem.setRightBarButtonItems([item1, negativeSpace, item2], animated: false)

How can I make the right bar items close and the title always centered? Like this: enter image description here

Edit: That's how the bar looks with a short title: enter image description here

The title is thankfully centered for it, but the spacing around buttons on the right is way too big.

Edit 2: Tried the solution from navigation bar right bar button items spacing - did not work. Did not change the look of navigation bar in the slightest, whatever frame size I tried to set.


Solution

  • You can center the title by using two buttons on each side - with the 2nd button on the left being a "blank" button...

    enter image description here

    enter image description here

    enter image description here

    enter image description here

    Example code:

    class ViewController: UIViewController {
        
        override func viewDidLoad() {
            super.viewDidLoad()
    
            view.backgroundColor = .systemBackground
            
            guard let img1 = UIImage(named: "nav1"),
                  let img2 = UIImage(named: "nav2"),
                  let img3 = UIImage(named: "nav3")
            else { fatalError() }
            
            let b1 = UIButton()
            let b2 = UIButton()
            let b3 = UIButton()
            let b4 = UIButton()
            
            b1.setImage(img1, for: [])
            b2.setImage(img2, for: [])
            b3.setImage(img3, for: [])
            // b4 - no image
    
            // all buttons set to 24x24
            [b1, b2, b3, b4].forEach { v in
                v.widthAnchor.constraint(equalToConstant: 24.0).isActive = true
                v.heightAnchor.constraint(equalTo: v.widthAnchor).isActive = true
            }
    
            let item1 = UIBarButtonItem(customView: b1)
            let item2 = UIBarButtonItem(customView: b2)
    
            let item3 = UIBarButtonItem(customView: b3)
            let item4 = UIBarButtonItem(customView: b4)
            
            self.navigationItem.setRightBarButtonItems([item1, item2], animated: false)
            self.navigationItem.setLeftBarButtonItems([item3, item4], animated: false)
    
            self.title = "This Test Title will be Truncated"
    
        }
        
    }