ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [IOS] LayoutIfNeeded
    IOS/VIEW 2022. 1. 19. 01:02

    Main Run Loop

    ios는 어플리케이현이 실행되면 UIApplication이 메인 스레드에서 main run loop를 실행시키고 main run loop에서 view의 위치 변화, 이벤트 등이 핸들러에게 권한을 부여해 처리된다.
    Update Cycle


    main run loop에서 이벤트를 통해 view의 위치나 상태가 변화는 경우가 있다. 이런 변화는 핸들러가 종료되고 main run loop로 권한이 돌아오는 시점인 update cycle에서 view의 변화를 적용시킨다.(코드와 실제 뷰 변화에 시간차가 존재한다. 하지만 그 시간은 너무 짧아 사용자가 체감할 수 없다.)

    UIVIew methods

    UIView에는 setNeedsLayout과 layoutIfNeeded를 비롯해서 여러 내장 메소드를 가지고 있다.

    • layoutSubViews()
      view의 값을 호출한 즉시 변경시켜주는 메소드. 호출되면 해당 View의 모든 SubView들의 layoutSubViews() 또한 연달아 호출한다. -> 비용이 많이들기 때문에 직접 호출하는 것은 지양된다. 이는 시스템에서 View의 값이 재계산 되어야 하는 적절한 시점(udpate cycle)에 자동으로 호출된다.
      UIViewController내의 뷰가 재 계산되어 다시 그려지는 행위가 발생하면 layoutSubViews가 호출 되고 View가 갱신되고 나면 뒤이어 UIViewController의 viewDidLayoutSubviews가 호출된다. 그렇기 때문에 갱신된 View 값에 의존하는 행위들은 viewDidLayoutSubviews에 명시해 주어야 한다.
      아래 상황에서는 layoutSubviews를 update cycle에서 자동으로 호출되는 상황이다.
    1. View의 크기를 조절할 때
    2. Subview를 추가할 때
    3. 사용자가 UIScrollView를 Scroll 할 때.
    4. 디바이스를 회전시켰을 때.
    5. View의 Auto Layout contrarint 값을 변경 했을 때
      하지만 layoutSubView를 수동으로 예약할 수 있는 메소드도 존재한다.
    • setNeedsLayout()
      layoutSubViews를 예약하는 행위중 가장 비용이 적게드는 방법이다. 이 메소드를 호출한 View는 재계산되어야 하는 View라고 수동으로 체크가 되며 update cycle에서 layoutSubViews가 호출되게 된다. 이 메소드는 미 동기적으로 작동하기 때문에 호출되고 바로 반환된다. 그리고 View의 보여지는 모습은 update cycle에 들어갔을 때 바뀌게 된다.
    • layoutIfNeeded()
      이 메소드는 또한 수동으로 layoutSubviews를 예약하는 행위지만 해당 예약을 바로 실행시키는 동기적으로 작동하는 메소드이다.
      update clycle이 올때까지 기다려 LayoutSubviews를 호출시키는 것이 아니라 그 즉시 layoutSubviews를 발생시키는 메소드이다.
      만일 main run loop에서 하나의 View가 setNeedsLayout을 호출하고 그다음 layoutIfNeeded를 호출한다면 layoutIfNeeded는 즉시 View의 값을 재계산하고 화면에 반영하기 때문에 setNeedsLayout이 예약한 layoutSubViews메소드는 update clycle에서 반영해야할 변경된 값이 존재하지 않기 때문에 호출되지 않습니다.
      때문에 layoutIfNeeded는 그 즉시 값이 변경되어야 하는 애니메이션에서 많이 사용된다. 만일 setNeedsLayout을 사용한다면 애니메이션 블록에서 그즉시 View의 값이 변경되는 것이 아니라 추 후 update cycle에서 값이 반영되므로 값의 변경은 이루어지지만 애니메이션 효과는 볼 수 없다.
      setNeedsLayout과 layoutIfNeeded의 차이점은 동기와 비동기의 차이이다.

    참고

Designed by Tistory.