ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • View의 life cycle (layoutsubviews에 대해)
    Swift 2021. 12. 31. 15:14

    우선 View와 관련된 life cycle을 확인할 필요가 있다.

    ViewController가 layout 을 잡는 과정이랄까?

     

    우선 layoutifneeded 와 setNeedsLayout의 개념을 이해하고 있다는 가정으로 설명한다. (모르시는분은 애플 공식문서 확인고고!)

     

    layoutsubviews() 

    우리가 layout을 변경하거나, 그릴때 layoutsubviews() 가 호출되며 반영한다.

    공식문서를 보면 직접 호출하지 말라고 되어있는데, 그러면 이 layoutsubviews() 가 호출될때 이부분을 viewcontroller에서 수정해 다룰 수 있게 다음 메소드 들이 있다.

     

    viewWillLayoutSubviews 

     -> layoutsubviews -> 레이아웃 정보 변경사항 뷰에 반영~

    viewDidLayoutSubviews

     

    이렇게 반영된다고 생각하면된다. 

     

    그래서 viewWillLayoutSubviews, viewDidLayoutSubviews 를 override해서 작성하면 된다. 

    그런데 내가 예기치 못할때도 해당 메소드가 불릴때가 있다고 한다. 그게 무슨말일까? 더 디테일하게 layoutsubviews()의 호출 시점을 보자.


    View의 Cycle

    그렇다면, View를 로드했을때 처음부터 모든 Cycle이 어떤식으로 흐를까? (ViewController의 생명주기를 이해했다는 바탕으로 아래와 같다) - 메소드 위주로 아래와 같다.

     

    1. loadView : LoadView is only called once: when the view needs to be loaded.
    2. viewDidLoad : Memory에 올림
    3. viewWillAppear
    4. viewWillLayoutSubviews
    5. viewDidLayoutSubviews
    6. viewDidAppear

    즉 처음 뷰를 그릴때 layoutsubviews()를 호출하기때문에 해당 메소드 들이 있다면 호출되는 셈이다.


    layoutIfNeeded, setNeedsLayout 은 ?

    topConstraint.constant = 100
    
    DispatchQueue.main.async {
    
    self.view.layoutIfNeeded()
    
    }

     

    이렇게 호출하면

     

    viewwilllayoutsubview

    viewDidLayoutSubviews

     

    호출됨.

     

    근데

    topConstraint.constant = 100
    
    DispatchQueue.main.async {
    
    self.view.setNeedsLayout()
    
    }

     

    viewwilllayoutsubview

    viewDidLayoutSubviews

    viewwilllayoutsubview

    viewDidLayoutSubviews

     

    왜 ㅐ두번 호출되지…?

    그건 바로바로


    결론

    그냥 레이아웃이 수정되면 업데이트 사이클에서 반영을 이때 layoutsubviews()가 호출되면 각각 viewWillLayoutSubviews, viewDidLayoutSubviews가 호출된다.

     

    하지만 우리가 수동으로 레이아웃의 변경을 update cycle에서 반영해달라고 요청하는데 그런 함수인 layoutIfNeeded, SetNeedsLayout 은 다음과 같은 차이가 있다.

    self.view.layoutIfNeeded 이거는 layoutSubviews 호출하지만, viewWillLayoutSubviews, viewDidLayoutSubviews를 호출하지 않는다는 차이가 있음.

    => 그럼 위의 상황이 이해가 간다.

     

    아래는 참고,

    LayoutSubViews() - Don’t call directly, instead call setNeedsLayout(),override if constraint base not offer expected behaviour.

    SetNeedsLayout()- Call on main thread, it wait for next drawing cycle. good for performance.

    LayoutIfNeeded() - Layout subviews immediately.

    (출처 : 공식문서에 나와있는 내용임)

    728x90

    'Swift' 카테고리의 다른 글

    UIView-Encapsulated-Layout-Width 오류  (0) 2022.03.24
    Associated type?  (0) 2022.01.04
    Xcode Cloud란  (0) 2021.12.28
    Swift AsyncSequence (비동기 시퀀스에 대한 지원)  (0) 2021.12.22
    Feature flags in Swift  (0) 2021.12.22

    댓글

Designed by Tistory.