2

I have migrated my app from Swift 3.1 to Swift 4.0 (Xcode 8.3.3 to Xcode 9.0) and some part of my interface is broken now. Navigation Bar of Navigation controller is complete mess. Please, look at screenshot: enter image description here

There are 3 elements:

  • left Netfnet logo (image)

  • right Signal strength (image)

  • right QR Code button

As you can see, two images are too big and not in center and button was deformed (it should be perfect square, all images too). There is code which generated navigation controller:

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        settings()
    }

    func settings() {
        let color = UIColor(red: 81 / 255, green: 155 / 255, blue: 22 / 255, alpha: 1.0)
        self.navigationController?.navigationBar.barTintColor = color

        let logoImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 35, height: 35))
        logoImageView.contentMode = .scaleAspectFit
        let logo = UIImage(named: "littleLogoImage")
        logoImageView.image = logo
        navigationItem.leftBarButtonItem = UIBarButtonItem(customView: logoImageView)

        let signalStengthImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 35, height: 35))
        signalStengthImageView.contentMode = .scaleAspectFit
        signalStengthImageView.image = UIImage(named: "signalStrength4")
        let signalStengthImageItem = UIBarButtonItem(customView: signalStengthImageView)

        let button = UIButton(type: .custom)
        button.setImage(UIImage(named: "qrCodeButton"), for: .normal)
        button.frame = CGRect(x: 0, y: 0, width: 35, height: 35)
        let qrCodeButtonItem = UIBarButtonItem(customView: button)

        navigationItem.rightBarButtonItems = [qrCodeButtonItem, signalStengthImageItem] //
    }

}

I can decrease resolution of images directly myself, but I just don't get why everting was fine in Swift 3.1 and in Swift 4.0 is broken.

I will be thankful for any help or advice.

Alex
  • 1,038
  • 2
  • 12
  • 32

2 Answers2

2

You have to add width and height constraints.

Your barImageView and barButton in CustomNavigationController should be like below :

func barImageView(imageName: String) -> UIBarButtonItem {
    let imgView = imageView(imageName: imageName)
    let widthConstraint = imgView.widthAnchor.constraint(equalToConstant: 35)
    let heightConstraint = imgView.heightAnchor.constraint(equalToConstant: 35)
    heightConstraint.isActive = true
    widthConstraint.isActive = true
    return UIBarButtonItem(customView: imgView)
}

func barButton(imageName: String, selector: Selector) -> UIBarButtonItem {
    let button = UIButton(type: .custom)
    button.setImage(UIImage(named: imageName), for: .normal)
    button.frame = CGRect(x: 0, y: 0, width: 35, height: 35)
    button.addTarget(self, action: selector, for: .touchUpInside)
    let widthConstraint = button.widthAnchor.constraint(equalToConstant: 35)
    let heightConstraint = button.heightAnchor.constraint(equalToConstant: 35)
    heightConstraint.isActive = true
    widthConstraint.isActive = true
    return UIBarButtonItem(customView: button)
}

Your signalStengthImageView in LogoWithSignalStrength:

signalStengthImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 35, height: 35))
signalStengthImageView.contentMode = .scaleAspectFit
let widthConstraint = signalStengthImageView.widthAnchor.constraint(equalToConstant: 35)
let heightConstraint = signalStengthImageView.heightAnchor.constraint(equalToConstant: 35)
heightConstraint.isActive = true
widthConstraint.isActive = true
Vini App
  • 7,339
  • 2
  • 26
  • 43
2

In Xcode 9, Navigation bar items are constraints base, Add this:

if #available(iOS 11.0, *) {
     logoImageView.widthAnchor.constraint(equalToConstant: 35).isActive = true
     logoImageView.heightAnchor.constraint(equalToConstant: 35).isActive = true
} else {
   //set frames
}
Irfan
  • 5,070
  • 1
  • 28
  • 32
  • Thank you for your answer but this checking is not necessary. My deployment target is 10.3 and everything is working without checking even on real devices. Thank you for help! – Alex Oct 02 '17 at 10:29