Subclass UINavigationBar SWIFT

Viewed 99

I want to pose my problem with the hope that someone can help me:

I created a subclass of UINavigationBar, adding an image as a background.

here is the code:

class NavigationBarN: UINavigationBar {

let customHeight: CGFloat = UIScreen.main.bounds.height / 8

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    translatesAutoresizingMaskIntoConstraints = true
    self.barStyle = UIBarStyle.black

    self.tintColor = .white
}

override init(frame: CGRect) {
    super.init(frame: frame)
    translatesAutoresizingMaskIntoConstraints = true
    self.barStyle = UIBarStyle.black

    self.tintColor = .white
}

override func sizeThatFits(_ size: CGSize) -> CGSize {
    return CGSize(width: UIScreen.main.bounds.width, height: customHeight)
}
var i = 0
override open func layoutSubviews() {
    super.layoutSubviews()

    frame = CGRect(x: frame.origin.x, y: 0, width: frame.size.width, height: customHeight) // problem here

    for subview in self.subviews {
        var stringFromClass = NSStringFromClass(subview.classForCoder)
        if stringFromClass.contains("BarBackground") {
            subview.frame = CGRect(x: 0, y: 0, width: self.frame.width, height: self.frame.height)

            let imageViewBackground = UIImageView(frame: CGRect(x: 0, y: 0, width: frame.size.width, height: customHeight))
            imageViewBackground.image = UIImage(named: “Image”1)
            imageViewBackground.contentMode = .scaleToFill
            subview.addSubview(imageViewBackground)


        }

        stringFromClass = NSStringFromClass(subview.classForCoder)
        if stringFromClass.contains("BarContent") {
            let centerY = subview.frame.heigh
            subview.frame = CGRect(x: subview.frame.origin.x, y: centerY, width: subview.frame.width, height: subview.frame.height)
        }

    }
}


/*
// Only override draw() if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func draw(_ rect: CGRect) {
    // Drawing code
}
*/

}

Up to iOS 11, it works without problems since iOS 12 the problems begin, the subclass enters an infinite loop. However the infinite loop occurs only when I try to initialize a new VC through the "navigationController? .PushViewController" function, otherwise it works.

The line of code causing the loop apparently is:

frame = CGRect(x: frame.origin.x, y: 0, width: frame.size.width, height: customHeight)

But removing it the navigation bar is not created correctly.

Anyone have any solution?

Thank You

1 Answers

You shouldn't change your frame in layoutSubviews – you should only be laying out your subviews. Changing the size of the frame in layoutSubviews couples the layout and sizing of the view, which you shouldn't do.

It's likely that under the hood, UINavigationBar is calling setNeedsLayout when its frame gets set.

Related