새소식

iOS

Auto Layout 라이프사이클 한눈에 볼 수 있게 정리하기

  • -

UIView가 생성되면 아래 3단계를 거치는데, 이 3단계는 단방향으로만 일어나는 것이 아니라 특정 단계가 이전 단계나 전체 단계를 다시 트리거링 할 수 있다. 한 사이클이 1/60초에 실행된다. 각 단계의 메소드들은 main run loop의 마지막 부분인 update cycle에서 호출되므로 직접 호출해서는 안된다.

Update step - updateConstraints()

  • 하는 일: 시스템이 view에 필요한 constraint들을 계산하고 설정
  • 호출시점
    • 시스템이 자동으로 호출하는 경우: view hierarchy에서 bottom-up 순으로 호출
      • constraint 활성화/비활성화
      • constraint 값, 우선순위 변경
      • view를 view hierarchy에서 삭제
    • 명시적으로 호출을 요청하는 방법
      • setNeedsUpdateConstraints(): 다음 update cycle에 호출하도록 트리거링
      • updateConstraintsIfNeeded(): constraint update flag가 설정(아래 방법으로 가능)되어 있다면 즉시 호출하도록 트리거링. auto layout 사용 시에만 유효.
        • 자동으로 설정
        • setNeedsUpdateConstraints() 호출
        • invalidateIntrinsicContentSize() 호출(intrinsicContentSize가 다음 update cycle에 다시 계산되도록 함)
  • 오버라이드
    • 언제하는가?
      • 최적화된 동적 constraint를 구현하고 싶을 때(정적인 constraint는 InterfaceBuilder나 view 생성자, viewDidLoad() 에서 구현)
    • 주의할 점
      • super.updateConstraints() 호출할 것

Layout Step - layoutSubviews()

  • 하는 일: 레이아웃 엔진이 view의 frame과 자식 view들의 frame을 계산하고 배치(모든 자식 view의 layoutSubviews()를 재귀호출하므로 부하가 크다)
  • 호출 시점 
    • 시스템이 자동으로 호출하는 경우: view hierarchy에서 top-down 순으로 호출
      • view resizing
      • subView 추가
      • UIScrollView 스크롤될 때 scrollview와 그 부모 view에 호출
      • 디바이스 회전
      • constraint 변경
    • 명시적으로 호출을 요청하는 방법
      • setNeedsLayout(): 다음 update cycle에 호출하도록 트리거링
      • layoutIfNeeded(): 즉시 호출하도록 트리거링
  • 오버라이드
    • 언제하는가?
      • constraint로는 충분하지 않을 때
      • frame을 직접 계산할 때
    • 주의할 점
      • super.layoutSubviews() 호출할 것
      • setNeedsLayout()이나 setNeedsUpdateConstraints()를 호출하지 말 것(무한루프에 빠짐)
      • 현재 view hierarchay 외부의 constraint를 수정하지 말 것
      • 현재 view hierarchay 내부의 constraint를 수정하는 것도 Update Step과 Layout Step을 트리거링하기 때문에 무한루프에 빠지지 않도록 주의할 것

Render Step - draw(_:)

  • 하는 일: view의 속성 중 크기나 위치를 제외한 색, 텍스트, 이미지, CoreGraphics 등을 그림(자식 view들의 draw(_:)를 호출하지 않음). auto layout 사용 여부와 관계 없음.
  • 호출 시점
    • 시스템이 자동으로 호출하는 경우: view hierarchy에서 top-down 순으로 호출
      • bounds 변경
    • 명시적으로 호출을 요청하는 방법 
      • setNeedsDisplay(): 다음 update cycle에 호출하도록 트리거링
      • displayIfNeeded()는 UIView에 존재하지 않으며, CALayer, NSView, NSWindow에만 존재(다음 update cycle까지 기다리는 것만으로 충분하다고 하는데 모바일의 특성상 성능 이슈 때문이 아닐까?)
  • 오버라이드
    • 언제하는가?
      • CoreGraphics, UIKit을 커스터마이즈하고 싶을 때
    • 주의할 점
      • super.draw(_:)를 꼭 호출할 필요는 없음

요약


ViewController에서는?

  • Update Step: updateViewConstraints()
  • Layout Step: viewWillLayoutSubviews(), viewDidLayoutSubViews()
  • viewDidLayoutSubViews()가 모든 subview의 bounds가 결정된 직후, 아직 view가 화면에 나타나기 전에 불리는 곳이므로 이 때 view의 변화가 필요한 경우 유용할 수 있다.

UIViewController와 UIView의 라이프사이클


참고

http://tech.gc.com/demystifying-ios-layout/

 

Demystifying iOS Layout

Some of the most difficult issues to avoid or debug when you first start building iOS applications are those dealing with view layout and content. Often, these issues happen because of misconceptions about when view updates actually occur. Understanding ho

tech.gc.com

https://medium.com/mj-studio/%EB%B2%88%EC%97%AD-ios-%EB%A0%88%EC%9D%B4%EC%95%84%EC%9B%83%EC%9D%98-%EB%AF%B8%EC%8A%A4%ED%84%B0%EB%A6%AC%EB%A5%BC-%ED%8C%8C%ED%97%A4%EC%B9%98%EB%8B%A4-2cfa99e942f9

 

[번역] iOS 레이아웃의 미스터리를 파헤치다

iOS의 UIView가 그려지는 과정과 메소드들을 살펴봅니다.

medium.com

https://www.vadimbulavin.com/view-auto-layout-life-cycle/

 

UIView Auto Layout life cycle

Understanding UIView life cycle is crucial to save time and avoid naive mistake when building iOS apps. In this article let's discuss each steps from view's auto layout life cycle as well as the notions of alignment rectangle and intrinsic content size.

www.vadimbulavin.com

https://jeonyeohun.tistory.com/336

 

[iOS] iOS는 화면을 어떻게 그릴까? RunLoop 부터 Constraint, Layout, Display 까지

런루프부터 화면에 뷰가 그려지기까지. 스터디를 하면서 기술발표가 있었는데요, 준비한 내용을 정리해두겠습니다! 거의 피피티에 모든걸 다 담아서 글은 많이 없을 것 같아요ㅎㅎ RunLoop(런루

jeonyeohun.tistory.com

 

반응형

'iOS' 카테고리의 다른 글

RunLoop  (0) 2023.07.25
UIView와 CALayer  (0) 2023.07.21
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.