UIView: [Apple] draw(_:)

J.Noma·2022년 2월 6일
0

iOS : View : UIKit

목록 보기
7/17

Reference


// - rect : view의 bound
func draw(_ rect: CGRect)

Remind

  • draw()는 직접 호출하는게 아니다. re-draw가 필요하면 setNeedsDisplay() 호출
  • UIView의 draw()는 내용이 없으므로 굳이 super를 호출할 필요는 없다
  • UIGraphicsGetCurrentContext는 변경될 수 있으므로 강한참조하면 안된다

🔸 Override 해야 하는 경우

이 메서드에 기본적으론 아무 내용도 구현되어 있지 않습니다만, CoreGraphics/UIKit라던지 content를 그려야 하는 subclass들은 이 메서드를 반드시 override해야 해서 drawing 코드를 구현해주어야 합니다. 만약 view가 "다른 방식"으로 content를 설정하고 있다면 override를 해줄 필요는 없습니다. "다른 방식"의 예로, 어떤 view가 단순히 background color를 표시하는 역할이라면 프로퍼티 설정만으로 해결됩니다. 다른 예로는, content를 layer 객체를 사용하여 직접적으로 설정하고 있다면 override가 불필요합니다

🔸 Graphics Context

이 메서드가 호출될 쯤이면, UIKit은 해당 view를 위한 drawing environment를 적절히 설정해놓았을 것이므로 단순히 drawing 함수/메서드를 호출하여 content를 렌더링할 수 있습니다. 특히, UIKit은 drawing을 위해 graphics context를 생성/설정합니다. 그리고 context의 origin을 view bounds 사각형의 origin과 매칭하기 위해 context의 transform을 조정합니다. 우리는 UIGraphicsGetCurrentContext() 함수를 통해 graphics context에 대한 참조를 얻어올 수 있습니다. 단, 강한 참조로 하면 안됩니다. draw() 메서드 호출들 사이에 변경될 수 있기 때문입니다. (참조타입임에도 변경에 대비하라는 것을 보니 context는 값변경만 되는게 아닌 인스턴스 자체가 생성/해제 cycle을 타는 듯합니다)

🔸 OpenGL ES

유사하게, OpenGL ESGLKView class를 사용하여 그리는 경우, GLKitdraw() 혹은 glkView()가 호출되기 전에 근본 OpenGL ES context를 적절히 설정합니다. 그래서 content를 렌더링하는데 필요한 모든 OpenGL ES 커맨드를 간단히 실행할 수 있습니다. OpenGL ES에 대한 더 많은 정보는 OpenGL ES Programming Guide를 참고합니다

🔸 rect / isOpaque

모든 drawing은 rect 파라미터에 명시한 사각형으로 제한해야 합니다. 추가로, view의 isOpaque 프로퍼티가 true라면, draw() 메서드는 opaque content와 함께 명시된 사각형을 반드시 꽉 채워야 합니다

🔸 Subclassing Notes

만약 UIView를 직속으로 subclassing하는 경우엔 이 메서드를 override하여도 super를 호출할 필요는 없습니다. 하지만, 다른 view class를 subclassing하는 경우엔 부모 view class에서 뭔가를 구현했을 수 있으니 override 시 super를 호출해야 합니다

🔸 Re-draw 메서드 (setNeedsDisplay)

이 메서드는 view가 처음 표시되거나, 이미 보여지고 있던 부분을 invalidate하는 이벤트가 발생할 때 호출됩니다. 이 메서드를 직접적으로 호출하면 안됩니다. 대신 view의 일부를 invalidate하여 redraw할 필요가 있을 경우, setNeedsDisplay() 메서드를 호출합니다

profile
노션으로 이사갑니다 https://tungsten-run-778.notion.site/Study-Archive-98e51c3793684d428070695d5722d1fe

0개의 댓글