Search code examples
iosswiftuinavigationbarnslayoutconstraint

Auto-layout on a View for a Navigation Bar's title


I have a simple class that creates a UIView containing a label. I want to use that view as the central section of a UINavigationBar, with 2 buttons on either side. The code below works well without adding the label:

class myView : UIView {
    override init(frame: CGRect) {
        super.init(frame: frame)

        self.backgroundColor = .green
    }
}

I call the class so:

let avatar = UIBarButtonItem(image: avatarImage, ...)
let otherButton = UIBarButtonItem(image: otherImage, ...)

navigationItem.leftBarButtonItems  = [avatar]
navigationItem.rightBarButtonItems = [otherButton]

let headerTitle = myView(frame: .zero)
headerTitle.translatesAutoresizingMaskIntoConstraints = false
navigationItem.titleView = headerTitleView

But if I add the label inside the UIView:

class myView : UIView {
    override init(frame: CGRect) {
        super.init(frame: frame)

        self.backgroundColor = .green

        let theLabel = UILabel(frame: .zero)
        theLabel.text = "The Title"
        theLabel.textAlignment = .center
        theLabel.translatesAutoresizingMaskIntoConstraints = false

        self.addSubview(theLabel!)
    }
}

.. I see the label, but it is stuck to the far left of the view. If I try to add constraints to the label, something like this:

NSLayoutConstraint.activate([
    theLabel.centerXAnchor.constraint(equalTo: self.centerXAnchor),
    theLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor)
])

.. it crashes, since the size of self (the UIView) is still .zero.

I've tried various combinations of layoutIfNeeded() and sizeToFit(), but with no success so far. How do I place a view as a title for a navigation bar, and layout elements inside that view?


Solution

  • I guees it's an order error

    self.addSubview(theLabel) // first
    NSLayoutConstraint.activate([  // then second
      theLabel.centerXAnchor.constraint(equalTo: self.centerXAnchor),
      theLabel.centerYAnchor.constraint(equalTo: self.centerYAnchor)
    ])