Search code examples
iosswiftconstraints

Why adding frame doesn't show a UIView when initializing with lazy var in Swift


I'm working on a Swift project and there is one thing I'm not clear about making UIs programmatically. I tried to display a simple UIView on the screen.

lazy var container: UIView = {
    let view = UIView(frame: CGRect(x: 0, y: 0, width: 30, height: 30))
    view.backgroundColor = UIColor.systemImageGray()
    view.layer.cornerRadius = view.layer.bounds.width / 2
    view.clipsToBounds = true
    return view
}()

override func viewDidLoad() {
    super.viewDidLoad()
    view.addSubview(container)
    setupConstraints()
}

func setupConstraints() {
    container.translatesAutoresizingMaskIntoConstraints = false
    NSLayoutConstraint.activate([
        container.topAnchor.constraint(equalTo: self.topAnchor, constant: 14),
        container.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -14),
        container.widthAnchor.constraint(equalToConstant: 30),
        container.heightAnchor.constraint(equalToConstant: 30)
    ])
}

The code above works fine, but since I set the with and height twice, I feel it's redundant, like UIView(frame: CGRect(x: 0, y: 0, width: 30, height: 30)) and set the width and height constraints in setupConstraints.

Since I set the width and height in UIView's frame, I thought I don't need to set the width and height constraints in the setupConstraints, but it doesn't show the view unless I add the width and height constraints again. So in this case, why I cannot set the width and height in UIView(frame: CGRect(x: 0, y: 0, width: 30, height: 30)) and I also have to add the width/height constraints again?


Solution

  • frame is useful when you are not using the Autolayout engine to place your views.

    When you do:

    container.translatesAutoresizingMaskIntoConstraints = false
    

    You are explicitly telling the engine to ignore the frame & that you are responsible for applying a new set of constraints.

    And hence you eventually do:

    NSLayoutConstraint.activate([
        container.topAnchor.constraint(equalTo: self.topAnchor, constant: 14),
        container.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -14),
        container.widthAnchor.constraint(equalToConstant: 30),
        container.heightAnchor.constraint(equalToConstant: 30)
    ])
    

    Which sets the positioning & dynamic sizing as per Autolayout's expectations.


    translatesAutoresizingMaskIntoConstraints

    A Boolean value that determines whether the view’s autoresizing mask is translated into Auto Layout constraints.

    Ref: https://developer.apple.com/documentation/uikit/uiview/1622572-translatesautoresizingmaskintoco