-
setNeedsDisplay & setNeedsLayoutiOS 2021. 12. 23. 13:05
안녕하세요.
오늘은 비슷해보이는 두 친구들이죠.
setNeedsDisplay와 setNeedsLayout에 대해서 알아보도록 하겠습니다.
두 메소드 이름만 봐서는 무엇인가를 세팅하는 거 같은데요.
먼제 setNeedDisplay부터 알아보도록 하겠습니다.
setNeedsDisplay
https://developer.apple.com/documentation/uikit/uiview/1622437-setneedsdisplay
Apple Developer Documentation
developer.apple.com
setNeedsDisplay는 UIView의 메소드입니다.
View의 전체 bounds를 다시 그려야 한다고 표시한다고 하네요.
다시 그리면 그렸지 표시한다는게 좀 낯섭니다.
이를 이해하기 위해서는Update Cycle을 이해해야 합니다.
https://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
앱이 이벤트 처리를 마치는 시점이 Update Cycle 지점입니다.
이 시점에서 시스템은 디스플레이 뿐만 아니라 레이아웃과 제약조건을 업데이트하는데요.
setNeedsDisplay함수를 호출하면 이 시점에 View를 다시 그리라고 알려주는 것입니다.
그런데 저희는 여태까지 이 함수를 호출한 적이 없는데 view가 제대로 그려졌자나요?
사실 UI와 직접적인 관련이 있는 프로퍼티가 변경이 되면 이 setNeedsDisplay함수가 저절로 호출된다고 합니다.
배경색을 바꾸든지 안에 있는 컨텐츠를 바꾸든지 하면 말이에요.
그럼 이 함수를 직접 호출해야하는 경우는 언제냐!
바로 UI와 직접적인 연관이 없는 프로퍼티가 변경되었을 때 UI를 변경해야하는 경우에요.
https://stackoverflow.com/questions/10818319/when-do-i-need-to-call-setneedsdisplay-in-ios
When do I need to call setNeedsDisplay in iOS?
When creating an iOS app, I'm confused as to when exactly I need to call setNeedsDisplay? I know that it has something to do with updating/redrawing the UI; however, do I need to call this every t...
stackoverflow.com
위의 질문의 답변으로 움직이는 원을 보여주고 있는 view가 존재할 때
그 view는 원의 중심의 좌표나 지름의 크기를 가지고 있자나요??
class CircleView: UIView { private var x: Int private var y: Int private var radius: Int ... }
그 프로퍼티는 Int타입이든 Double 타입이든 UI와 직접적인 관계가 있지는 않습니다.
그럴 경우 중심의 좌표나 지름의 크기가 변했을 때 View를 바뀐 정보로 다시 그려줘야 하는데
UI와 직접적인 연관이 있는 프로퍼티가 아니라 view가 저절로 업데이트가 되지 않아요.
class CircleView: UIView { private var x: Int = 0 { didSet { self.setNeedsDisplay() } } private var y: Int = 0 { didSet { self.setNeedsDisplay() } } private var radius: Int = 0 { didSet { self.setNeedsDisplay() } } }
따라서 이런 식으로 값이 변경되었을 경우 setNeedsDisplay를 호출해주어야 합니다.
근데 이런식으로만 작성한다면 x좌표가 어디로 움직여야하는지 view가 알리가 없자나요??
이럴 때 draw 메소드가 호출됩니다.
view를 다시 그린다는건 결국 draw 메소드를 호출한다는 것인데요.
setNeedsDisplay도 draw를 호출해줘!라고 말하는 겁니다.
그래서 이름을 setNeedsDraw로 하는게 맞지 않을까하는 글을 본 거 같기도 합니다 ㅎㅎ
https://developer.apple.com/documentation/uikit/uiview/1622529-draw
Apple Developer Documentation
developer.apple.com
draw함수는 저희가 customView를 만들지 않는 이상 재정의 할 필요가 없습니다.
또한 이 함수는 절대로 개발자가 직접 호출해서는 안됩니다.
시스템이 알아서 적절한 시점에 이 함수를 호출하거든요.
override func draw(_ rect: CGRect) { change(x: self.x, y: self.y) change(radius: self.radius) }
이런 식으로 draw함수를 작성하면 좌표와 지름이 변경될 때마다 해당 값에 맞춰서 view를 다시 그립니다.
setNeedsLayout
https://developer.apple.com/documentation/uikit/uiview/1622601-setneedslayout/
Apple Developer Documentation
developer.apple.com
setNeedsDisplay와 비슷한데 얘는 layout과 관련된 메소드 같죠?
맞습니다.
setNeedsLayout 메소드는 layout의 재설정이 필요하다는 것을 시스템에게 알려줍니다.
그러면 setNeedsDisplay의 경우와 마찬가지로 updateCycle에 layout을 업데이트하는 것입니다.
setNeedsDisplay가 draw함수를 호출해줘라고 했던 것처럼
setNeedsLayout은 layoutSubviews를 호출해달라고 시스템에게 알립니다.
오늘은 setNeedsDisplay와 setNeedsLayout을 알아보았는데요.
두 친구 모두 Update Cycle 시점에 시스템에게 작업을 하라고 시키는 것은 동일한데요.
그것이 draw냐 layoutSubviews냐에 차이입니다.
혹시 잘못된 내용이나 더 알려주고 싶은 내용이 있으시면 알려주시면 감사하겠습니다.
'iOS' 카테고리의 다른 글
동시성 프로그래밍(2) Serial(직렬) VS Concurrency(동시) (0) 2022.02.04 동시성 프로그래밍(1) Sync(동기) VS Async(비동기) (0) 2022.02.03 Storyboard VS Code(Programmatically) (0) 2021.12.21 Hugging & Compression Resistance (0) 2021.12.21 ARC(Automatic Reference Counting) (0) 2021.12.20