As many of iOS developer known, layoutIfNeeded and setNeedsLayout are two methods that can be used to update the layout of a view and its subviews. But what are their differences? Today's article will help this out:

LayoutIfNeeded

layoutIfNeeded is a method that forces the view to immediately update its layout and the layout of its subviews. This can be extremely useful when you need to ensure that the view is properly rendered before other activities, such as animating a change in the view's layout. However, using layoutIfNeeded can be expensive in terms of performance, since it causes the view to update its layout immediately, rather than waiting for the next update cycle.

Simple Example:

class MyViewController: UIViewController {
  let newView = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))

  override func viewDidLoad() {
    super.viewDidLoad()
    view.addSubview(newView)
  }

  func updateNewView() {
    UIView.animate(withDuration: 0.3) {
      self.newView.backgroundColor = .blue
      self.view.layoutIfNeeded()
    }
  }
}

In the example above, when updateNewView method is called, it will trigger an update on the layout, which will ensure all the properties are taken into account when the layout is updated, leading to a smooth animation.

SetNeedsLayout

Similarly, setNeedsLayout is a another built-in method that marks the view as needing to update its layout, but doesn't force the update to happen immediately. Instead, the view's layout will be updated during the next update cycle, which normlly happens just before the view is displayed on the screen. This can be a more efficient approach than using layoutIfNeeded, since it allows the view to update its layout at a more optimal time, rather than immediately. However, it can also mean that the view's layout may not be updated immediately, which may not be suitable in some situations. Let's take a look at an exmaple:

class MyViewController: UIViewController {

  let newView = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))

  override func viewDidLoad() {
    super.viewDidLoad()
    
    newView.backgroundColor = UIColor.red
  }
  
  func changeColor(_ sender: UIButton) {
    newView.backgroundColor = UIColor.blue
    newView.setNeedsLayout()
  }
}

When call the method changeColor, it will force the newView to change the color in the next update.

When should I choose them?

Based on the context above, the choice of those two methods to will much depend on the needs. In practise, layoutIfNeeded is highly recommended to used for cases when we want to make sure that a view's layout will be updated immediately, while setNeedsLayout is more suitable used when the user can afford to wait for the next update cycle to update the view's layout.