공부를하게 된 배경에 있어서 그동안 iOS UI 업데이트 관련해서 문제가 발생하면
많은 솔루션들이 layoutIfNeeded()를 호출해라. 라는 솔루션들이 많았다.
setNeedsDisplay()
layoutIfNeeded()
와 같은 코드들이 있다.
뭐... 근데 호출해서 해결 됐던 적은 많았다.
기존에 이해는 "그냥 뷰가 바뀌었으니 업데이트 해줘!" 라는 메소드 정도로 어림잡아 이해했는데, 이번에 이를 좀 더 깊게 이해해보고자 한다.
한 UIView는 아래와 같은 Cycle을 돌면서 뷰를 관리 해준다.
위에서는 강제로 View를 다시 그리는 트리거에 올리기 위해서 setNeedsDisplay()를 호출 했다.
그럼 setNeedsLayout()은?
거의 비슷한 내용이다. 업데이트하는 대상이 다를 뿐.
Display: 사각형 내의 요소들을 draw해주는 의미
Layout: 사각형 자체의 크기와 위치를 layout 시키는 의미
그럼 다음 Drawing Cycle에 레이아웃에 대한 업데이트가 필요하다면 setNeedsLayout()을 호출해주면 되겠다.
setNeedsDisplay()에서 draw()와 비슷한 함수가 layoutSubViews()가 있는데 이 역시도 Cycle에서 자동으로 호출해주므로 직접 호출을 지양하며 필요시 override해 사용할 수 있겠다.
해당 메소드는 setNeedsLayout()과 기능은 같지만 Cycle을 기다리지 않고 곧바로 layout을 실행한다는 의미를 가지고 있다.
setNeedsLayout vs layoutIfNeeded Explained
차이는 이곳에서 볼 수 있다.
사실 위에서 언급한 바와 같이 대부분의 layout/draw 요청은 3가지 트리거에 의해 걸려 신경을 쓰지 않는 것이 일반적이다. 그러나 내가 CustomView를 구현한다거나 복잡한 애니메이션등을 구현할 때, 위의 트리거에 걸리지 않아서 변경이 안되거나 늦는 경우가 종종 발생하는 것을 경험했다.
사전에 예방할 수도 있겠지만 위의 메소드 들은 문제가 발생했을 때, 솔루션이 되지 않을까 싶다.
ex) 어? 뷰가 업데이트가 안돼요! 값이 안바뀌어요! 등등...