iOS: When layoutIfNeeded() is called on a specific subview, it is not displayed on the screen

41 Views Asked by At

I am dynamically adding and displaying a custom view. At this time, the custom view has subviews.

When showing a custom view and additionally showing internal subviews, I am curious as to why the position of that view is not reflected in the parent view if layoutIfNeeded() is called on a specific subview.

Below is my code.

final class RotationCardView: UIView {
  ...
  private lazy var gradientLabel = GradientAnimatedLabel()

  override init(frame: CGRect) {
    super.init(frame: frame)
    ...
  }

  required init?(coder: NSCoder) { nil }

  override var intrinsicContentSize: CGSize {
    return CGSize(width: 200, height: 200)
  }

  func setGradientLabel() {
    let minimumTopSpacing = 5.0
    gradientLabel.text = "# cute cat card"
    gradientLabel.alpha = 0
    addSubview(gradientLabel)
    let gradientLabelBottomConstraint = gradientLabel.topAnchor.constraint(
    equalTo: bottomAnchor,
    constant: minimumTopSpacing - gradientLabel.intrinsicContentSize.height/2)

    NSLayoutConstraint.activate([
      gradientLabelBottomConstraint,
      gradientLabel.trailingAnchor.constraint(equalTo: trailingAnchor)])
    self.layoutIfNeeded()
  }
}

I added this custom view to the ViewController's view: After that I have logic to call setGradientLabel() when the button is pressed.

When I call setGradientLabel(), the gradinetLabel is displayed after being laid out on the screen.

But what I'm curious about here is when gradientLabel.layoutIfNeeded() is used instead of self.layoutIfNeeded() within the setGradientLabel() function.

func setGradientLabel() {
  ...    
  // [comment1]
  NSLayoutConstraint.activate([
    gradientLabelBottomConstraint,
    gradientLabel.trailingAnchor.constraint(equalTo: trailingAnchor)])
  gradientLabel.layoutIfNeeded() // gradientLabel is not displayed on the screen.
}

As shown in the code snippet above, if I call layoutIfNeeded() of gradientLayer inside the setGradientLabel() function, [comment1] The layout added below is not applied and is not displayed on the screen.

The picture below is the view hierarchy.

enter image description here

In the above code, in order for the gradientLabel I wanted to be displayed directly in the RotationCardView, is it desirable to call layoutIfNeeded() on the view to which the gradientLabel constraint has been added?

0

There are 0 best solutions below