본문 바로가기

스위프트

[CoreGraphics] CGContext를 통해 뷰를 커스터마이징하게 그려보자

- 목표 : Apple의 Native 프레임워크인 CoreGraphics와 UIKit API를 통해 커스텀 뷰 클래스에서 Draw를 커스터마이징하게 하는 API들을 알아보자.

 

Core Graphics

Quartz 기술을 이용하여 가벼운 2D 렌더링을 고화질 출력과 함께 수행하는 프레임워크이다. Path 기반의 드로잉, 안티앨리어싱 렌더링, 그라디언트, 이미지, 컬러 관리, PDF 문서 등을 다룰 수 있다.

 

Core Graphics 프레임워크는 뛰어난 드로잉 엔진인 Quartz를 기반으로 한 프레임워크이다. 매칭되지 않는 출력 품질과 함께 저레벨/가벼운 2D 렌더링을 제공한다. 이 프레임워크를 통해 Path 기반의 드로잉, 트랜스 폼, 컬러 관리, Offscreen 렌더링, 패턴, 그라디언트, 쉐이딩, 이미지 데이터 관리, 이미지 생성, 이미지 마스킹, PDF 문서 생성/보여주기/파싱을 할 수 있다.

 

맥 OS에선 Core Graphics는 또한 하드웨어 디스플레이, 저레벨 유저 인풋 이벤트, 윈도잉 시스템과 함께 서비스를 제공한다.

 

정리하면 Quartz를 이용하여 2D 렌더링을 할 수 있는 기능의 집합인 것 같다.

해당 프레임워크 클래스 중에 CGContext가 있는데, 해당 클래스를 이용하여 실제로 뷰의 커스터마이징한 드로잉을 진행할 수 있다.

 

CGContext

Quartz를 활용한 2D 드로잉 환경 객체이다. CGContext 타입은 Quartz 드로잉 목적지를 대표한다. 그래픽 컨텍스트는 드로잉 파라미터, 각 비트맵 이미지/PDF 문서/프린터/어플리케이션안에 인도우에 있는 모든 대상들을 그리기 위해 필요한 모든 디바이스 특화 정보를 포함하고 있다.

 

수 많은 API가 있지만 Path 기반으로 커스터마이징하게 그릴 수 있는 API들을 알아봐서 어떠한 상황에서도 원하는 형태의 드로잉을 해볼 수 있도록 알아보자.

override func draw(_ rect: CGRect) {
        print(#function)

        guard let context = UIGraphicsGetCurrentContext() else {
            return
        }

        let size = bounds.size

        // func move(to: CGPoint) : 특정 Path 의 첫 시작 Point를 지정한다.
        context.move(to: CGPoint(x: 0, y: 0))

        // func addLine(to: CGPoint) : 현 Path 마지막 포인트를 기준으로 CGPoint까지 라인 한 줄을 추가한다.
        context.addLine(to: CGPoint(x: size.width / 2, y: size.height / 2))
        context.addLine(to: CGPoint(x: size.width, y: 0))
        context.addLine(to: CGPoint(x: size.width, y: size.height))
        context.addLine(to: CGPoint(x: .zero, y: size.height))
        context.addLine(to: CGPoint(x: 0, y: 0))

        // func closePath() : Sub Path의 종료를 나타낸다.
        context.closePath()

        context.setLineWidth(3.0)
        context.setStrokeColor(UIColor.red.cgColor)
        context.setFillColor(UIColor.blue.cgColor)

        // func drawPath(using: CGPathDrawingMode) : Mode에 따라 현재 Context에 셋된 Path를 그린다.
        context.drawPath(using: .fillStroke)

        context.setFillColor(UIColor.green.withAlphaComponent(0.5).cgColor)

        // func fill(CGRect) : 특정 영역을 색으로 채워 그린다.
        context.fill(CGRect(origin: .zero,
                            size: CGSize(width: size.width / 3, height: size.height)))

        context.setStrokeColor(UIColor.yellow.withAlphaComponent(0.5).cgColor)

        context.stroke(CGRect(origin: CGPoint(x: size.width / 2, y: 0),
                              size: CGSize(width: 50, height: 100)))
    }

각 path, fill, stroke를 통해 특정 영역에 drawing을 임의로 할 수 있다.