kmell96
kmell96

Reputation: 1465

iOS Ensure Bar Button Items Appear Full-Size in UINavigationBar on iPhone SE

In my app, I have a navigation bar where I'm using three buttons on the right side. I create it like this:

let button1 = UIBarButtonItem(image: UIImage(named: "button1"),
                              style: .plain,
                              target: self,
                              action: #selector(self.button1Tapped))

// Repeat for button2 and button3

navigationItem.rightBarButtonItems = [button1, button2, button3]

This works as expected, except on iPhone SE. It seems like there is some sort of fixed limit on what percentage of the navigation bar width the right bar buttons can take up, and this limit is exceeded on the small screen of the iPhone SE. So, the rightmost button gets shrunk down to about half the size of the other buttons.

I'm not setting a title, so there's more than enough space for all 3 buttons to be full size - even on iPhone SE. However, I'm not sure how to specify that in code; is there some way to increase this limit (or whatever feature causes the button to shrink) to ensure that all of the BarButtonItems appear full size on iPhone SE?

Upvotes: 0

Views: 380

Answers (2)

mobs_boss
mobs_boss

Reputation: 852

You can declare these properties

let contentView = UIView()
let buttonOneImageView = UIImageView()
let buttonTwoImageView = UIImageView()
let buttonThreeImageView = UIImageView()

assign a UIView to titleView property of navigationItem of ViewController as a workaround

fileprivate func buttonOneImageViewConstraints() {
    buttonOneImageView.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
    buttonOneImageView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
    buttonOneImageView.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: -8).isActive = true
    buttonOneImageView.widthAnchor.constraint(equalTo: buttonOneImageView.heightAnchor).isActive = true
}

fileprivate func buttonOneConstraints(_ button1: UIButton) {
    //button1 constraints
    button1.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
    button1.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
    button1.rightAnchor.constraint(equalTo: contentView.rightAnchor, constant: -8).isActive = true
    button1.widthAnchor.constraint(equalTo: button1.heightAnchor).isActive = true
}

fileprivate func buttonTwoImageViewConstraints() {
    buttonTwoImageView.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
    buttonTwoImageView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
    buttonTwoImageView.rightAnchor.constraint(equalTo: buttonOneImageView.leftAnchor, constant: -8).isActive = true
    buttonTwoImageView.widthAnchor.constraint(equalTo: buttonTwoImageView.heightAnchor).isActive = true
}

fileprivate func buttonTwoConstraints(_ button1: UIButton,_ button2: UIButton) {
    //button2 constraints
    button2.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
    button2.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
    button2.rightAnchor.constraint(equalTo: button1.leftAnchor, constant: -8).isActive = true
    button2.widthAnchor.constraint(equalTo: button2.heightAnchor).isActive = true
}

fileprivate func buttonThreeImageViewConstraints() {
    buttonThreeImageView.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
    buttonThreeImageView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
    buttonThreeImageView.rightAnchor.constraint(equalTo: buttonTwoImageView.leftAnchor, constant: -8).isActive = true
    buttonThreeImageView.widthAnchor.constraint(equalTo: buttonThreeImageView.heightAnchor).isActive = true
}

fileprivate func buttonThreeConstraints(_ button2: UIButton,_ button3: UIButton) {
    //button3 constraints
    button3.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
    button3.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
    button3.rightAnchor.constraint(equalTo: button2.leftAnchor, constant: -8).isActive = true
    button3.widthAnchor.constraint(equalTo: button3.heightAnchor).isActive = true
}

fileprivate func contentViewConstraints(_ titleView: UIView) {
    //setting constraints for contentView
    contentView.rightAnchor.constraint(equalTo: titleView.rightAnchor).isActive = true
    contentView.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width).isActive = true
    contentView.centerXAnchor.constraint(equalTo: titleView.centerXAnchor).isActive = true
    contentView.centerYAnchor.constraint(equalTo: titleView.centerYAnchor).isActive = true
    self.navigationItem.titleView = titleView
}

func setupNavBar() {

    contentView.backgroundColor = .black
    contentView.translatesAutoresizingMaskIntoConstraints = false

    let titleView = UIView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 40))
    titleView.addSubview(contentView)


    buttonOneImageView.translatesAutoresizingMaskIntoConstraints = false
    buttonOneImageView.contentMode = .scaleAspectFit
    buttonOneImageView.image = #imageLiteral(resourceName: "contacts-settings")
    contentView.addSubview(buttonOneImageView)

    //add button1
    let button1 = UIButton(type: .roundedRect)
    button1.translatesAutoresizingMaskIntoConstraints = false
    button1.addTarget(self, action: #selector(buttonOneFunction), for: .touchUpInside)
    contentView.addSubview(button1)

    buttonTwoImageView.translatesAutoresizingMaskIntoConstraints = false
    buttonTwoImageView.contentMode = .scaleAspectFit
    buttonTwoImageView.image = #imageLiteral(resourceName: "contacts-history")
    contentView.addSubview(buttonTwoImageView)

    //add button2
    let button2 = UIButton(type: .roundedRect)
    button2.translatesAutoresizingMaskIntoConstraints = false
    button2.addTarget(self, action: #selector(buttonTwoFunction), for: .touchUpInside)
    contentView.addSubview(button2)

    buttonThreeImageView.translatesAutoresizingMaskIntoConstraints = false
    buttonThreeImageView.contentMode = .scaleAspectFit
    buttonThreeImageView.image = #imageLiteral(resourceName: "contacts-person")
    contentView.addSubview(buttonThreeImageView)

    //add button3
    let button3 = UIButton(type: .roundedRect)
    button3.translatesAutoresizingMaskIntoConstraints = false
    button3.addTarget(self, action: #selector(buttonThreeFunction), for: .touchUpInside)
    contentView.addSubview(button3)


    DispatchQueue.main.asyncAfter(deadline: .now()) {
        self.buttonOneImageViewConstraints()
        self.buttonOneConstraints(button1)
        self.buttonTwoImageViewConstraints()
        self.buttonTwoConstraints(button1, button2)
        self.buttonThreeImageViewConstraints()
        self.buttonThreeConstraints(button2, button3)
        self.contentViewConstraints(titleView)
    }

}

Similarly,

@objc func buttonTwoFunction() {
    print("button 2 tapped")
}

@objc func buttonThreeFunction() {
    print("button 3 tapped")
}

Upvotes: 0

Lance Samaria
Lance Samaria

Reputation: 19622

This isn't the most eloquent way of doing things but it should work.

The iPhone SE screen's dimensions are w:320 x h:568 Apple Screen Display Sizes

You could possibly resize the images for the iPhone SE and do something like this:

var button1: UIBarButtonItem!
var button2: UIBarButtonItem!
var button2: UIBarButtonItem!

// check the screen's dimensions
if UIScreen.main.bounds.width == 320 && UIScreen.main.bounds.height == 568{

    // you may have to play around with it but resize the UIImage(named: "button1") to fit the iPhone SE
    button1 = UIBarButtonItem(image: UIImage(named: "button1_Resized"),
                              style: .plain,
                              target: self,
                              action: #selector(self.button1Tapped))

    // Repeat for button2 and button3
    // resize the UIImage(named: "button2_Resized") and UIImage(named: "button3_Resized") to fit the iPhone SE

} else{

    // anything other then the iPhone SE will get the regular sized images
    button1 = UIBarButtonItem(image: UIImage(named: "button1"),
                              style: .plain,
                              target: self,
                              action: #selector(self.button1Tapped))

    // Repeat for button2 and button3
}

navigationItem.rightBarButtonItems = [button1, button2, button3]

Upvotes: 1

Related Questions