setNeedsLayout() vs layoutIfNeeded 차이점
View의 layout을 갱신시키는 메소드들 중 setNeedsLayout()
와 layoutIfNeeded()
의 차이점을
자세히 몰랐는데 한 번 정리할 필요가 있다고 생각되어 공식문서를 보며 공부해야겠다!
setNeedsLayout() vs layoutIfNeeded 차이점
두 메소드의 차이점을 알기전에 먼저 main run loop라는 것을 알아야 합니다.
iOS에는 main run loop라는 것이 존재합니다.
main run loop동안에 application은 사용자의 이벤트를 받아들이고 개발자가 짜놓은 코드에 따라 적절한 response를 취해줍니다.
response가 다 취해지고 다시 main loop에 return이 되면 이제 update cycle로 진입하게 됩니다.
update cycle은 layout을 재배치 하거나 view들을 다시 그리는 작업을 진행하게 됩니다.
그래서 이벤트 핸들링중에 뷰를 변화시키는 요청이 들어오면 이 update cycle에서 갱신을 해주는 작업을 진행하는것 입니다.
iOS app같은 경우, 화면이 보통 60fps이므로 이 update cycle의 갱신주기 같은 경우도 1/60초가 되겠군요.
그래서 뷰를 갱신하고 싶어도 이 갱신주기가 되어야만 갱신을 할 수 있습니다.
그런데 뷰를 즉각적으로 갱신하고 싶은 경우도 있잖아요??? 그래서 위의 두 가지 메소드가 존재하는 것입니다.
두 메소드가 호출 되면 공통적으로 view를 갱신하는 메소드인 layoutSubviews()
가 호출됩니다.
UIView의 method인 layoutSubviews()
입니다. 설명은 간단하죠 :)
이 메소드는 view와 모든 subview들의 위치와 사이즈를 재계산하여 배치시켜줍니다.
그래서 이 메소드는 매우 expensive하다고 표현합니다.
그래서인지는 모르겠지만 공식문서에서는 이 함수를 직접 호출 할 수 없고,setNeedsLayout()
와 layoutIfNeeded()
을 통해서 뷰를 갱신하라고 말해줍니다.
그럼 이제! 드디어! 하나씩 알아봅시다!
setNeedsLayout()
layoutIfNeeded()
둘의 설명은 간단합니다. layout을 갱신해주는 메소드죠.
하지만 가장 큰 차이점은 언제 갱신을 하느냐 입니다.
setNeedsLayout()
은 다음 update cycle에,layoutIfNeeded()
은 즉시
갱신해달라고 요청하는 메소드입니다.
하지만 아래와 같은 상황은 위 메소드를 호출하지 않아도 시스템에서 바로 layoutSubviews()
를 호출합니다.
- Resizing a view
- Adding a subview
- User scrolling a UIScrollView (layoutSubviews is called on the UIScrollView and its superview)
- User rotating their device
- Updating a view’s constraints
이런 상황에서는 굳이 갱신 메소드들을 사용할 필요가 없겠죠?! :)
레이아웃은 개발 시에 필수 요소인데 이렇게 간단하게라도 정리하니 더 이해가 되는 것 같습니다..!!!
아래 그림은 view와 viewController의 layout관련 메소드의 호출 순서입니다.
레이아웃을 조정하기 위해선 아래 순서는 숙지해야할 것 같습니다!!
Reference
Run Loops
Layout Update Cycle
layoutSubviews()
setNeedsLayout()
layoutIfNeeded()
ViewController, View layout Methods