Drawing Cycle

Eli·2021년 2월 7일
3

iOS

목록 보기
4/11

About Windows and Views

iOS Drawing Concepts

공부를하게 된 배경에 있어서 그동안 iOS UI 업데이트 관련해서 문제가 발생하면
많은 솔루션들이 layoutIfNeeded()를 호출해라. 라는 솔루션들이 많았다.

setNeedsDisplay()
layoutIfNeeded()

와 같은 코드들이 있다.
뭐... 근데 호출해서 해결 됐던 적은 많았다.

기존에 이해는 "그냥 뷰가 바뀌었으니 업데이트 해줘!" 라는 메소드 정도로 어림잡아 이해했는데, 이번에 이를 좀 더 깊게 이해해보고자 한다.

iOS ) View/레이아웃 업데이트 관련 메소드

Drawing Cycle (setNeedsDisplay())

한 UIView는 아래와 같은 Cycle을 돌면서 뷰를 관리 해준다.

  1. UIView에 대해서 draw함수를 통해 그리기 요청. (ViewController라면 viewDidLoad 이후)
  2. iOS에서 UIView를 그리고 캡쳐본을 UIView에게 전달.
  3. UIView의 변화트리거가 있을 경우 → 다음 사이클때 캡쳐본을 무효화하고 새로 그림
  4. UIView의 변화트리거가 없을 경우 → draw함수가 호출되지 않음.
  5. 1~4 사라질 때 까지 Cycle을 반복

변화 트리거?

  1. View의 상위에 겹치는 frame에 있던 View가 사라지거나 이동.
  2. isHidden이 false로 할당.
  3. View가 화면 밖에 있다가 화면 내부로 들어올 때(ex, Scroll)
  4. UIView의 setNeedsDisplay 호출

setNeedsLayout()

위에서는 강제로 View를 다시 그리는 트리거에 올리기 위해서 setNeedsDisplay()를 호출 했다.

그럼 setNeedsLayout()은?
거의 비슷한 내용이다. 업데이트하는 대상이 다를 뿐.

Display: 사각형 내의 요소들을 draw해주는 의미
Layout: 사각형 자체의 크기와 위치를 layout 시키는 의미

그럼 다음 Drawing Cycle에 레이아웃에 대한 업데이트가 필요하다면 setNeedsLayout()을 호출해주면 되겠다.

setNeedsDisplay()에서 draw()와 비슷한 함수가 layoutSubViews()가 있는데 이 역시도 Cycle에서 자동으로 호출해주므로 직접 호출을 지양하며 필요시 override해 사용할 수 있겠다.

layoutIfNeeded()

해당 메소드는 setNeedsLayout()과 기능은 같지만 Cycle을 기다리지 않고 곧바로 layout을 실행한다는 의미를 가지고 있다.

setNeedsLayout vs layoutIfNeeded Explained

차이는 이곳에서 볼 수 있다.

결론

사실 위에서 언급한 바와 같이 대부분의 layout/draw 요청은 3가지 트리거에 의해 걸려 신경을 쓰지 않는 것이 일반적이다. 그러나 내가 CustomView를 구현한다거나 복잡한 애니메이션등을 구현할 때, 위의 트리거에 걸리지 않아서 변경이 안되거나 늦는 경우가 종종 발생하는 것을 경험했다.

사전에 예방할 수도 있겠지만 위의 메소드 들은 문제가 발생했을 때, 솔루션이 되지 않을까 싶다.

ex) 어? 뷰가 업데이트가 안돼요! 값이 안바뀌어요! 등등...

profile
애플을 좋아한다. 그래서 iOS 개발을 한다. @Kurly

0개의 댓글