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

41 Views Asked by At

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.

2

There are 2 best solutions below

0
DonMag On BEST ANSWER

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"

    }
    
}
3
Solomiya On

The title length in your sample and desired outcome is significantly different.

If the title is short enough iOS will try and put it in the centre automatically. Although if the title doesn't fit iOS tries to squeeze it in thus shifting it to the left.

Try out your code with a shorter title — most likely it will work like expected.