안녕하세요? 소들입니다 :)
오늘은 CALayer에 대해 공부해보려고 해요!
UIView는 다음과 같이 CALayer 타입의 layer 라는 프로퍼티를 갖고 있거든여
이 layer는 우리가 직접적이건 간접적이건
꽤나? 건드릴 일이 많은데 (View 그림자 및 테두리 생성, MasksToBounds 등등)
정확히 무엇을 하는 녀석인지는 모르고 쓰는 경우가 많은 것 같아요 (나또한)
근데 대충 뭔가 그릴 때 쓰는 것을 보아 그래픽과 관련이 있는 것 같지 않나요? :)
그래서 CALayer란 무엇이고, 어떻게 구성되어 있는지 공부해보려고 합니다!
모든 포스팅은 편의 말투로 합니다~!!
1. CALayer는 어떻게 등장했나
먼저 CALayer에서 접두사 CA는
Core Animation
의 약자임!! 그렇다면 Core Animation이 무엇일까?!!
그전에, iOS에서 그래픽에 우리가 어떻게 접근하게 된 것인지 배경?부터 설명 하겠음:)
자,
우리가 iOS 어플을 사용할 때 화면이 끊기지 않고 "부드럽게" 그려지도록하기 위해선 초당 60 프레임 속도를 유지해야 함
따라서 초당 60프레임을 계속 유지하기 위해, GPU에서 직접 실행되는 그래픽에 강력한 OpenGL이 생김
OpenGL의 최대 장점은 그래픽 하드웨어에 가장 빠르게 액세스 할 수 있다는 것임!!!
근.데. 단순한 작업에도 코드 양이 매우 방대해짐
(OpenGL 다뤄본 사람은 얼마나 난해한지 알거임 =_=)
따라서 OpenGL보다 더 적은 코드로 그래픽을 구현할 수 있는
Core Graphics라는 것을 만듦
(CGColor, CGRect 등등이 여기 속함)
근데 이 Core Graphics도 약간 Low Level 작업이라,
이것마저 더욱 간단하게 사용하도록 만들자!!해서 만든 게 Core Animation임
근데!! 여기서 끝이 아님
Core Animation에는 그래픽에 접근하는 많은 고급 기능이 들어있는데, 애플은 또
"근데 앱 만드는데 이렇게 고급 기능이 다 필요함? 아닌 것 같은데?"
라고 생각해 버린 것임 따라서
Core Animation을 또 간단하게 만들어버린 것이 바로 UIKit임
따라서 우린 UIKit을 통해 최고 High Level에서 그래픽에 접근을 할 수 있던 것임!
근데 단점이라 하면
계속 간단하게 단순화 시켜왔기 때문에 사용하긴 편할지 몰라도,
가장 Low Level에 있는 OpenGL이나 Core Graphics 보다는 적은(제한된) 기능을 제공할 수 밖에 없음
(상위 레벨로 갈 수록 하위 레벨의 모든 기능을 다루진 못했을테니)
쨌든 때문에 우린 UIKit에 속한 UIView를 이용하여 쉽고 간편하게 화면을 내맘대로 그릴 수 있던 것임!!
근데 우리가 화면에 그리는 UIView는 레이아웃, 터치 이벤트 등 많은 작업을 처리하긴 하지만
사실은 뷰 위에 컨텐츠나 애니메이션을 그리는 행위는 직접 하지 않음!!!
UIView는 직접 화면에 그리는 시각적 행위를 Core Animation에게 위임하는데,
그것이 바로 오늘 공부하는
layer
라는 CALayer 타입의 프로퍼티를 통해서임 :)
뭔가 애플 역사 설명한 것 같고 그래서 설명충 된 것 같고 그래서 길고 그렇긴 한데
난 이런 내용이 참 흥미롭기 때문에 써봄.. :))))))))))
2. UIView에서 CALayer의 구성
CALayer는 UIView에서 어떻게 구성되어 있는가!!!!!
부터 설명하자면
UIView는 하나의 CALayer(Root)만 가지고 있다
CALayer(Root)는 SubLayer를 여러 개 둘 수 있다
UIView의 SubView는 UIView의 CALayer(Root) 위에 얹혀지는 것이다
뭐 이론으론 이게 뭥미 할 수 있는데
그림으로 보면 다음과 같음
UIView에는 layer라는 CALayer 하나만 갖고 있지만,
layer는 CALayer를 자신의 SubLayer로 여러 개 둘 수 있음
(마치 UIView의 계층 구조처럼!)
3. CALayer 사용 예제
간단하게 언제 사용하는지 몇 가지 예제를 보여드리겠음
3-1. View의 모서리를 둥굴게 만들 때
myView.layer.cornerRadius = 100
|
3-2. View의 테두리를 만들 때
myView.layer.borderColor = UIColor.black.cgColor
myView.layer.borderWidth = 5
|
3-3. View에 CALayer를 통해 그림을 그릴 때
뭐 위 예제 외에 MasksToBounds, Shadow 등등 있지만 더는 안 다루고
마지막으로 CALayer가 자신의 SubLayer를 여러 개 둔다는 거에 대한 다뤄보겠음
let layer1: CALayer = CALayer()
layer1.frame = .init(x: 10, y: 10, width: 100, height: 100)
layer1.backgroundColor = UIColor.red.cgColor
myView.layer.addSublayer(layer1)
let layer2: CALayer = CALayer()
layer2.frame = .init(x: 120, y: 10, width: 100, height: 100)
layer2.backgroundColor = UIColor.red.cgColor
myView.layer.addSublayer(layer2)
let layer3: CALayer = CALayer()
layer3.frame = .init(x: 230, y: 10, width: 100, height: 100)
layer3.backgroundColor = UIColor.red.cgColor
myView.layer.addSublayer(layer3)
|
이렇게 CALayer를 Custom하게 만들어
myView의 Layer(Root)에다가 SubLayer로 붙여주면
짜잔 마치 myView의 SubView처럼 원하는 frame을 그릴 수 있음!!!!
UIView로도 위 그림 만들 수 있는데? 라고 할 수 있지만
UIView를 여러 개 생성하는 것보다, CALayer를 여러 개 생성하는 것이 훨씬 가볍다고 함!
따라서 UIView보다 나은 퍼포먼스를 기대할 수 있다고 함!
4. CALayer의 성능 문제 해결
CALayer로 애니메이션을 만드는 등 많은 효과를 넣으면
성능상에 문제를 일으켜 속도가 현저히 저하된다고 함
이때 성능상 문제를 해결해주는 2가지 프로퍼티를 소개하겠움
4-1. shouldRasterize
myView.layer.shouldRasterize = false
|
CALayer를 그릴 때 오직 한 번만 렌더링 할 건지에 대한 여부를 지정하는 속성으로,
default 값은 false 임
true = 레이어의 컨텐츠를 처음 한 번만 렌더링 하고 이후 애니메이션부턴 재활용됨
false(default) = 애니메이션 될 때마다 레이어의 모양을 다시 그림
언제 쓰기 적합하냐면
레이어의 컨텐츠가 화면 주변에서 움직이기는 하나, 모양은 변하지 않을 때 사용함
쨌든 이런 경우엔 true로 설정하면 성능이 향상된다고 함
4-2. drawsAsynchronously
myView.layer.drawsAsynchronously = false
|
CALayer를 그리는 데 필요한 CPU 작업을 Background Thread에서 수행해야하는지 여부를 지정하는의 속성으로,
default 값은 false 임
true = 드로잉 요청을 Background Thread에서 수행하겠다
false(default) = 드로잉 요청을 Main Thread에서 수행하겠다
얘는 shouldRasterize의 약간 반대? 개념이라고 보면 됨
레이어의 컨텐츠를 반복적으로 다시 그려야할 때 사용하면 성능이 향상된다고 함
.
.
.
오늘은 평소 좀 의문을 갖고 있던 CALayer에 대해 정리해 보았습니다 🌝
⭐️틀린 내용이나 피드백 적극 환 영⭐️
'iOS > iOS' 카테고리의 다른 글
iOS) CAGradientLayer - UIView에 그라데이션 넣기 (2) | 2020.11.19 |
---|---|
iOS) Color Literal - 코드에서 색상표 보기 (4) | 2020.11.12 |
iOS) UIKit / Foundation / Cocoa / Cocoa Touch (8) | 2020.11.09 |
iOS) ClipsToBounds vs MasksToBounds (0) | 2020.11.02 |
iOS) Frame vs Bounds 제대로 이해하기 (3/3) (11) | 2020.11.02 |