in Swift4, replacement of navigationItem.leftBarButtonItem resizes unwanted

484 views Asked by At

Having a problem with UIBarButtonItem resizing when returning to VC with different values for frame and image.

var selectedR = 1
var leftFrame = CGRect()
var leftImage = UIImage()

override func viewDidLoad() {
    super.viewDidLoad()

    if selectedR == 0
    {
        leftFrame = CGRect(x: 0, y: 0, width: 33, height: 33)
        leftImage = UIImage(named: “pic-0”)!
    }
    else if selectedR == 1
    {
        leftFrame = CGRect(x: 0, y: 0, width: 79, height: 33)
        leftImage = UIImage(named: "pic-1")!
    }
    else if selectedR == 2
    {
        leftFrame =  CGRect(x: 0, y: 0, width: 34, height: 33)
        leftImage = UIImage(named: "pic-2”)!
    }

    let cButton = UIButton(frame: leftFrame)
    cButton.setImage(leftImage, for: UIControlState())
    cButton.addTarget(self.revealViewController(), action: #selector(SWRevealViewController.revealToggle(_:)), for: .touchUpInside)
    cButton.contentMode = UIViewContentMode.scaleAspectFit
    let leftItem = UIBarButtonItem(customView: cButton)
    self.navigationItem.leftBarButtonItem = leftItem
}

First time perfect size for selectedR = 1

Coming back into viewDidLoad with different selectedR value and image blows up, distorts and setting the leftFrame size is not honoured.

This all worked perfect in swift 3, but swift 4 it goes all over the place. Any help or suggestions would be much appreciated.

1

There are 1 answers

0
beyowulf On BEST ANSWER

One major change between iOS 10 and 11 is now bar button items are laid out by the auto layout engine. Typically that should be backward compatible. But if you are having problems with laying out bar button items, you should try setting constraints and see if that solves your problem.

In you case you would say:

var selectedR = 1
var leftFrame = CGRect()
var leftImage = UIImage()

override func viewDidLoad() {
    super.viewDidLoad()

    if selectedR == 0
    {
        leftFrame = CGRect(x: 0, y: 0, width: 33, height: 33)
        leftImage = UIImage(named: “pic-0”)!
    }
    else if selectedR == 1
    {
        leftFrame = CGRect(x: 0, y: 0, width: 79, height: 33)
        leftImage = UIImage(named: "pic-1")!
    }
    else if selectedR == 2
    {
        leftFrame =  CGRect(x: 0, y: 0, width: 34, height: 33)
        leftImage = UIImage(named: "pic-2”)!
    }

    let cButton = UIButton(frame: leftFrame)
    cButton.widthAnchor.constraint(equalToConstant: leftFrame.width).isActive = true
    cButton.heightAnchor.constraint(equalToConstant: leftFrame.height).isActive = true
    cButton.setImage(leftImage, for: UIControlState())
    cButton.addTarget(self.revealViewController(), action: #selector(SWRevealViewController.revealToggle(_:)), for: .touchUpInside)
    cButton.contentMode = UIViewContentMode.scaleAspectFit
    let leftItem = UIBarButtonItem(customView: cButton)
    self.navigationItem.leftBarButtonItem = leftItem
}

This was covered in Apple's WWDC 2017 session Updating Your App for iOS 11.