setNeedsLayout 과 LayoutIfNeeded

zoe·2023년 12월 6일
0
post-custom-banner

layoutSubViews()

  • view의 값을 호출한 즉시 변경시켜주는 메서드
  • 호출되면 해당 View의 모든 SubView들의 layoutSubviews()이 연달아 호출된다
  • 비용이 많이 드는 메서드이고, 때문에 직접 호출하는 것은 지양된다

아래의 경우에서는 자동으로 layoutSubviews() 메서드 호출이 예약된다

  • view의 크기를 조절할 때
  • subView를 추가할 때
  • 사용자가 UIScrollView를 스크롤 할 때
  • 디바이스를 회전시켰을 때(Portrait, Landscape)
  • View의 AutoLayout constraint값을 변경시켰을 때

하지만 수동으로 layoutSubviews()를 예약하고 싶다면?

layoutSubviews를 유도할 수 있는 여러 방법이 존재한다 -> layoutIfNeeded / setNeedsLayout
이는 일종의 update cycle에서 layoutSubviews의 호출을 예약하는 행위라고 할 수 있다

layoutIfNeeded()

Use this method to force the view to update its layout immediately. When using Auto Layout, the layout engine updates the position of views as needed to satisfy changes in constraints. Using the view that receives the message as the root view, this method lays out the view subtree starting at the root. If no layout updates are pending, this method exits without modifying the layout or calling any layout-related callbacks.

이 방법은 뷰가 레이아웃을 즉시 업데이트하도록 합니다. 오토레이아웃을 사용하는 경우 레이아웃 엔진은 constraints의 변경 사항을 충족하기 위해 뷰 위치를 업데이트합니다. 이 방법은 메시지를 수신하는 뷰를 루트뷰로 사용하여 뷰 하위 트리를 루트부터 배치합니다. 보류 중인 레이아웃 업데이트가 없는 경우 이 메서드는 레이아웃을 수정하거나 레이아웃 관련 콜백을 호출하지 않고 종료됩니다.

setNeedsLayout()

Call this method on your application’s main thread when you want to adjust the layout of a view’s subviews. Because this method does not force an immediate update, but instead waits for the next update cycle, you can use it to invalidate the layout of multiple views before any of those views are updated. This behavior allows you to consolidate all of your layout updates to one update cycle, which is usually better for performance.

뷰의 서브뷰 레이아웃을 조정하려면 프로그램의 기본 스레드에서 이 메소드를 호출하십시오. 이 방법은 즉시 업데이트를 수행하지 않고 대신 다음 업데이트 주기를 기다리기 때문에 뷰가 업데이트되기 전에 여러 뷰의 레이아웃을 무효화할 수 있습니다. 이 동작을 통해 모든 레이아웃 업데이트를 한 번의 업데이트 주기로 통합할 수 있으므로 일반적으로 성능이 더 좋습니다.

둘의 공통점

수동으로 layoutSubviews()를 예약하는 행위이이다

둘의 차이점

layoutIfNeeded는

  • 해당 예약을 바로 실행시키는 동기적으로작동하는 메서드이다
  • update cycle이 올 때까지 기다리는것이 아니라 그 즉시 layoutSubviews()를 발동시킨다

setNeedsLayout은

  • 비동기적으로 작동한다
  • layoutSubviews()를 예약하는 행위 중 가장 비용이 적게 드는 방법이다
  • 이 메소드를 호출한 View는 재계산되어야 하는 View라고 수동으로 체크가 되며 update cycle에서 layoutSubviews()가 호출되게 된다
  • View의 보여지는 모습은 update cycle에 들어갔을 때 바뀌게 된다

참고
https://baked-corn.tistory.com/105
RunLoop가 무엇일까? https://babbab2.tistory.com/68

profile
개발하면서 마주친 문제들을 정리하는 공간입니다.
post-custom-banner

0개의 댓글