CALayer란
👋 들어가기 전
CALayer는 정말 일반적인 사용목적을 제외하고는 직접 건드리지 않아, 지식이 너무 기초에 머물러있다.
UI에 대한 기초적인 지식을 향상시키고 싶어, 회사에서 디자인 시스템 파트부분을 지원해 합류하게됐는데,
어제 회의에서, CALayer에 대한 얘기가 많이나왔고, 나는 당연히 이해하는 수준이 많이 떨어졌다.

이번 기회를 통해 CALayer에 대한 기본정도는 알고 넘어가보자..
🏁 학습할 내용
- iOS에서 Graphic 작업의 역사
- 잘못 알고있던 View와 Layer의 역할
- CALayer란
- 언제 직접 건드릴까??
🎨 iOS에서 Graphic 작업의 역사

wikipedia를 살펴보면, iOS와 관련든 그래픽 모델이 많은데
우리는 여기서, 핵심적인 내용을 정말 간단하게만 알아보자.
우리가 살펴볼 요소들을 그림으로 보면 다음과 같다.

1. OpenGL (Core OpenGL)
2D, 3D 그래픽 랜더링과 GPU에서 실행
먼저 OpenGL부터 살펴보자.
Open Graphics Library는 플랫폼과 언어에 독립적인 표준 그래픽 API로서, 2D,3D 그래픽 렌더링을 위해 탄생했다.
대부분 서비스는 불편한 사용감이 없는 최소 프레임은 초당 60프레임 이상이다.
OpenGL은 GPU에 직접 빠르게 접근해서 실행될 수 있단는 점이다.
하지만, 너무 low하고 많은 코드떄문에 진입장벽이 매우 높다는 단점이 있다.
Core OpenGL은 OpenGL의 방대한 내용중, Apple 생태계에서 사용하는 내용만
모아놓은 모음집이라고 생각하면된다.

2. Core Graphics
OpenGL보다 조금 더 개발자 친화적인 랜더링

먼저, Apple 공식 내용을 간단히 내용을 정리하면 다음과 같다.
- Apple이 만든 2D 드로잉 엔진
- 벡터 기반의 2D 그래픽 처리 API
- Quartz 그래픽 Layer(라이브러리) 있는 기술을 활용
- 2D 벡터 드로잉, 텍스트 랜더링, 비트맵 처리 등 다양한 2D 작업을 처리
- CG 접두어가 붙은 많은 API를 제공
여기서 두개의 흥미로운 내용이 있다.
Quartz란 무엇인가?
Quartz는 Apple의 2D 그래픽 기술 전체를 지칭하는 포괄적인 용어, 즉 그래픽 기술에 대한 라이브러리를 의미한다.
왜 벡터 기반으로 ??

백터 기반으로 그리게되면 가장 큰 장점은, 확대/ 축소 등 여러가지 품질 열화상황에서 대응이 가능하다.
내용은, 부스트 캠프 시절 공부했던 이미지 포맷 분석 포스팅을 참고하자
3. Core Animation
벡터 드로잉 기반 CoreGraphics 너무 low + 높은 프레임 속도와 부드러운 애니메이션

먼저, Apple 공식 내용을 간단히 내용을 정리하면 다음과 같다.
- 시작 및 끝 포인트를 기반으로 부드러운 애니메이션을 만드는 프레임워크
- 드로잉 작업을 그래픽 하드웨어로 전달하여, 랜더링 작업을 가속화해, 품질 저하 없는 높은 프레임과 부드러운 애니메이션 구현
- 코어 애니메이션은 View과 아닌 Layer를 통해 앱의 콘텐츠를 보여준다.
- 뷰가 가진 컨텐츠를 비트맵으로 변환하여 캐싱하고, GPU가 이 비트맵을 처리
여기서 중요한점은 우리가 오늘 배울려는 CALayer가 바로 Core Animation과 직접적인 이해관계가 있다는 것
애니메이션 처리

앱에 그림이 그려지면, 비트맵은 캐싱되고, 회전이 시작하면, 비트맵과 상태정보가 Core Animation -> GPU로 넘어가는 비트맵을 새로 생성한다.
이 때 GPU로 넘어간 비트맵이 뷰에 보이게 되는 것
뷰에서 컨텐츠를 그릴 때, 우리는 draw(rect:) 메서드를 이용하는데, 이 메서드는 뷰에서 호출되기 때문에 CPU를 사용함
하지만 Core Animation은 비트맵을 만들기 처리하기 때문에, GPU에서 처리가 가능하고, 뷰에 컨텐츠를 그리는 것보다
훨씬 더, 적은 비용으로 화면에 표시할 수 있다.
😂 잘못 알고있던 View와 Layer의 역할
1️⃣ View가 짱이다.
이벤트도 받고, 생명주기도 있고, layout도 설정하고 ,컨텐츠도 그리고해주고 특별한 일 없으면 , Layer는 필요없다.
2️⃣ Layer는 특별한 경우에만 사용한다.
대표적으로, cornerRadius라던지, 그림자라던지 등등, 특별할일 없으면 만날 일 없는 친구다..
내가 잘못 알고 있었던 내용은, UIView는 컨텐츠나 애니메이션을 직접 그리지않음, 그 작업을 사실 Layer가 하고 있던 것
여기서 왜 Layer에 그리는 지는 위 Core Animation의 애니메이션 처리를 살펴보자.
그렇다면 두 개념에 대해 한번 정확히 차이를 짚고 넘어가자.
| UIView | layer | |
| 선언 위치 | UIKit | Core Animation |
| 담당 스레드 | 메인 스레드 | 별도의 스레드 |
| sub 존재 | sbuview | subLayer |
| 이벤트 인식 및 상호작용 | UIResnpoder의 서브클래스 | X |
| 역할 | 유저와의 상호작용 인식 | 실제 랜더링과 애니메이션 |
간단하게 정리하면 위와 같다.
여기서 하나 깨닫는게, 컨텐츠 표시할 때, 왜 최적화와 퍼포먼스 향상을 위해, Core 쪽으로 가야한다는 의미를 알 것 같다.
스레드도 메인스레드를 사용하지않고, 조금 더 low한 곳에서 커스터마이징을 한다면 분명 성능은 좋아지는게 맞는 것 같다.
🌠 CALayer
✅ 정의

- View의 Backing Store를 제공, View의 위치,사이즈, 변형 등의 정보를 보관 및 관리한다.
- 코어에니메이션에서 캐싱한 데이터가 바로 Backing Store

- View 없이도, 시각적인 속성들을 가질 수 있고, 대표적으로 shadow, border, corner 등이 있다.


📍 특징
- layerClass 변수는 해당 뷰가, 어떤 종류 layer를 만들어내는지를 나타낸다.
- 기본값은 CALayer지만, ovrride를 통해 원하는 Layer를 반환할 수 있다.
- view는 layer의 delegate(대리자), CALayerDelegate를 채택 중
- Delegate 객체는 반드시, display(layer:) 또는 draw(layer: inContext:) 메서드가 구현되어 레이어 객체의 content를 그릴 수 있어야함
- 둘다 구현되어 있으경우, display(layer:)가 사용됨
♻️ UIVIew와 관계


1️⃣ UIView는 대응되는 RootLayer를 가지고 있다.
더 자세히말하면, CALayerDelegate에서 display 또는 draw 함수가 호출되면
그 결과가 rootLayer에 표시되면서 동시에 캐싱된다.
이후 컨텐츠를 표시할 때는 view는 컨텐츠를 보여주기위한 비용은 적게든다.
왜냐하며느, Backing Store를 layer에서 제공하기 때문에
2️⃣ RootLayer은 단, 한개지만, SubLayer는 여러개 둘 수 있다.
우리는 지금까지 여러 화면을 보여주기위해, View를 add해서 보여주고 있었지만, 실질적으로 컨텐츠를 보여주는 것은
layer이므로 layer를 여러개 쌓는게 성능적으로는 더 좋다.
그런데 우리는 addSubLayer보다 addSubiview가 익숙하잖아??
layer는 addSubview에서 어떤 변화가 있을까??
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
// 부모 뷰 (빨간색)
let parentView = UIView(frame: CGRect(x: 50, y: 100, width: 200, height: 200))
parentView.layer.name = "parentLayer"
view.addSubview(parentView)
// 자식 뷰 (파란색)
let childView = UIView(frame: CGRect(x: 50, y: 50, width: 100, height: 100))
childView.layer.name = "childLayer"
print("=== Before addSubview ===")
print("parentView.subviews:", parentView.subviews) // []
print("parentView.layer.sublayers:", parentView.layer.sublayers ?? [])
// addSubview 실행
parentView.addSubview(childView)
print("\n=== After addSubview ===")
print("parentView.subviews:", parentView.subviews.map{$0.backgroundColor}) // [childView]
print("parentView.layer.sublayers:", parentView.layer.sublayers?.compactMap{$0.name} ?? [])
// 레이어 비교
if let sublayer = parentView.layer.sublayers?.first {
print("childView.layer.name:" , childView.layer.name)
}
}
/*
=== Before addSubview ===
parentView.subviews: []
parentView.layer.sublayers: []
=== After addSubview ===
parentView.subviews: [Optional(UIExtendedSRGBColorSpace 0 0 1 1)]
parentView.layer.sublayers: ["childLayer"]
childView.layer.name: Optional("childLayer")
*/
결과를 살펴보면, 부모 뷰의 layer와 child뷰의 layer역시도, 부모 자식 관계(sub)가 성립되고 있는 걸 볼 수 있다.
정말 view없이 layer만 추가해야한다면, addSubLayer를 일방적인 view를 추가해도 layer도 추가되니 걱정 ㄴㄴ
출처
https://developer.apple.com/documentation/coregraphics
Core Graphics | Apple Developer Documentation
Harness the power of Quartz technology to perform lightweight 2D rendering with high-fidelity output. Handle path-based drawing, antialiased rendering, gradients, images, color management, PDF documents, and more.
developer.apple.com
https://en.wikipedia.org/wiki/Quartz_(graphics_layer)
Quartz (graphics layer) - Wikipedia
From Wikipedia, the free encyclopedia Graphics rendering system used in macOS This article needs to be updated. Please help update this article to reflect recent events or newly available information. (April 2021) In Apple's macOS operating system, Quartz
en.wikipedia.org
https://ko.wikipedia.org/wiki/%EB%B2%A1%ED%84%B0_%EA%B7%B8%EB%9E%98%ED%94%BD%EC%8A%A4
벡터 그래픽스 - 위키백과, 우리 모두의 백과사전
위키백과, 우리 모두의 백과사전. 다른 뜻에 대해서는 벡터 문서를 참고하십시오. 벡터 그래픽스와 래스터 그래픽스의 배율에 따른 비교를 보여주는 예시 벡터 그래픽스(vector graphics)는 컴퓨터
ko.wikipedia.org
https://developer.apple.com/documentation/quartzcore
https://developer.apple.com/documentation/QuartzCore/CALayer
CALayer | Apple Developer Documentation
An object that manages image-based content and allows you to perform animations on that content.
developer.apple.com
https://jeonyeohun.tistory.com/363
[iOS] view.layer의 정체를 찾아서
UIView와 CALayer 진짜 면접에서 자주 받는 질문인 UIVIew와 layer의 차이에 대해서 공식문서를 기반으로 공부해보려고 해요. 왜냐하면 저런 질문을 받았을 때 단 한 번도 명쾌하게 답변을 해본 적이 없
jeonyeohun.tistory.com
Core Animation Basics
Core Animation Basics Core Animation provides a general purpose system for animating views and other visual elements of your app. Core Animation is not a replacement for your app’s views. Instead, it is a technology that integrates with views to provide
developer.apple.com