티스토리 뷰
안녕하세요 Pingu입니다! 🐧
오늘은 모든 UIView에 존재하는 CALayer에 대해 알아보려고 합니다.
CALayer를 직접 사용해본 기억은 cornerRadius를 사용하여 뷰를 둥글게 만들 때랑 커스텀 AVPlayer를 만들 때? 정도밖에 없는 것 같은데, 얘가 어떤 역할을 하는지에 대한 개념이 정확하지 않아서 한 번 알아보려고 합니다.
일단 View에 존재하는 layer라는 프로퍼티의 정의를 살펴보겠습니다.
렌더링에 사용되는 뷰의 핵심 애니메이션 레이어라고 합니다. 렌더링은 학교에서 그래픽스 시간에 배운 기억이 있는데, 모델 또는 영상 등을 만드는 과정이었던 것으로 알고 있습니다. 어쨌든 뷰에 나타나는 애들을 만들어내는 곳이라고 이해하면 될 것 같아요.
그리고 눈에 들어오는 내용 중 하나인 절대로 nil이면 안된다고 합니다.
이 layer는 CALayer 객체인데, CALayer의 정의를 보게되면,
이미지 기반 콘텐츠를 관리하고 해당 콘텐츠에 애니메이션을 수행할 수 있는 객체라고 정의되어 있습니다. 참고로 CALayer에서 CA는 Core Animation의 줄임말이라고 하네요!
뷰의 backgroundColor, border, shadow와 같은 속성들도 모두 CALayer에 속해있다고 하네요. 또한 콘텐츠를 화면에 표시하는 데 사용되는 geometry라는 정보도 갖고 있습니다.
그럼 간단하게 한 번 실제로 뷰를 살펴봐야겠어요.
이를 위해서는 스토리보드가 아닌 코드로 뷰를 만들어서 분석해야겠네요.
오 진짜 UIView 객체 안에 layer라는 인스턴스가 존재합니다.
UIView를 상속하는 UIImageView도 layer라는 인스턴스를 갖고 있는 것을 볼 수 있습니다.
layer는 backgroundcolor, shadow, border 등을 처리해준다고 했는데, 실제로 되는지 살펴보겠습니다.
이렇게 UIView 객체의 layer에 backgroundColor로 색을 설정해주면
이렇게 원하는 색을 가진 UIView 객체가 만들어지게 됩니다.
근데 여기서 의문이 있습니다.
그냥 바로 UIView에 backgroundColor를 설정해줄 수도 있지 않나?라는 것이죠.
이렇게 UIView 자체에 인스턴스로도 backgroundColor가 존재하고 이걸로도 색을 바꿀 수 있습니다.
실제로 동작도 아주 잘 됩니다.
그럼 이게 지금 layer라는 애가 해주는 게 맞나? 싶은 생각이 드는 거죠.
그래서 실제 UIView의 backgroundColor 객체로 가보면 아래와 같이 선언되어있습니다.
다른 프로퍼티와는 다르게 backgroundColor에만 @NSCopying이 있는 게 보이시나요?
얘가 뭘 하는 애인가 해서 정의를 찾아봤더니 자기들끼리 기능적으로 동일하게 작동하도록 복사해주는 거였어요
근데 CALayer의 backgroundColor에 가 보시면 아래와 같이 정의되어 있습니다.
@NSCopying이라는 키워드가 없죠.
그리고 신기하게도 UIView의 모든 프로퍼티에 @NSCopying 이라는 키워드를 사용하는 것은 backgroundColor 뿐입니다.
CALayer와 이름이 같은 프로퍼티도 backgroundColor 하나뿐이죠.
제 생각에는 얘를 layer와 복사해서 쓰는 거 같은데... 확실하진 않습니다.
그냥 갑자기 궁금해서 좀 조사해봤네요 ㅋㅋㅋ
확실하게 알게 되면 글을 수정하도록 해야겠어요..
일단 결론적으로 UIView 객체에 나타나는 콘텐츠들을 관리하는 것이 layer의 역할이다!라고 볼 수 있습니다.
절대로 nil이 될 수도 없기 때문에 모든 UIView 객체는 layer를 가지고 있다고 할 수 있죠.
그리고 레이어에는 또 다른 레이어가 추가될 수 있고 이는 계층구조를 가지게 됩니다.
이걸 그림으로 나타내면 이렇게 나타낼 수 있어요.
공식문서에 따르면 뷰가 레이어를 둘러싸고 있다고 합니다.
레이어는 그리는 역할만 하기 때문에 다양한 이벤트를 처리하고 사용자와 상호작용을 할 수 없어서 이를 처리해주는 뷰와 함께 사용해야 한다고 합니다.
공식문서에 아래와 같은 내용이 있는데요
For example, if you wanted to use the same image in multiple places, you could load the image once and associate it with multiple standalone layer objects and add those objects to the layer tree. Each layer then refers to the source image rather than trying to create its own copy of that image in memory.
여러 레이어에서 동일한 이미지를 사용한다면, 해당 이미지를 한 번만 로드하고 한 번 로드한 이미지를 레이어들에서 계속 참조하여 사용하는 것이 좋다고 합니다.
근데 그냥 동일한 레이어를 여러개의 뷰에 넣어버리면 똑같은 효과를 가져다 주지 않을까요?
이 부분은 한 번 궁금하니 직접 해볼게요
저는 이렇게 코드를 짜서 myView1, myView2에 모두 제가 만든 레이어가 들어갈 줄 알았는데..
실제 결과에는 위와 같이 하나의 뷰에만 레이어가 추가되어있습니다.
그래서 실제로 레이어가 있는지를 봤는데...
이렇게 myView1에는 서브 레이어가 없다고 나옵니다.
즉 레이어는 한 번에 한 곳에만 존재할 수 있으며 동일한 레이어를 여러 군데에서 동시에 사용하더라도 마지막에 사용한 곳에서만 보인다는 것을 알 수 있습니다.
아까 공식문서에서 이미지를 여러 군데에서 참조형태로 사용하라는 말 처럼 여러개의 레이어를 만들어도 이미지는 한 번만 로드하여 계속 사용하는게 효율적이다 라는 것을 알 수 있어요.
2개의 서로 다른 레이어를 만들고 이를 추가해주니 원하는 대로 나오는 것을 볼 수 있습니다.
그리고 레이어는 뷰와는 다르게 자신의 슈퍼뷰의 bounds 밖을 알아서 잘라주지 않습니다.
위와 같이 View의 크기는 100*100으로 만들고 레이어는 200*200으로 만들어서 뷰의 서브 레이어로 추가해주게 되면 알아서 100*100으로 만들어주지 않는다는 말이에요.
이렇게 뷰를 덮어버리더라도 상관하지 않고 나와버립니다.
따라서 뷰의 bounds를 넘어서는 부분을 잘라주기 위해서는 masksToBounds라는 프로퍼티를 사용해주면 되는데요!
현재는 myView의 슈퍼레이어의 masksToBounds 프로퍼티를 수정하면 myView 크기만큼 레이어가 잘려서 보이게 됩니다.
딱 뷰의 크기만큼 잘리는 것을 볼 수 있어요.
이번 글은 약간 의식의 흐름대로 쓴 거 같네요...ㅎㅎ;;
자꾸만 새로운 게 궁금해져서 그냥 알아본 것들을 죄다 쓰다 보니 이렇게 된 것 같네요..
사실 레이어에는 더 많은 공부할 것들이 있더라구요!
이번글은 이정도로 쓰고 다음 글에서 더 알아보려고 합니다.
읽어주셔서 감사합니다!
참고 문서
'iOS > iOS_Memo' 카테고리의 다른 글
[iOS 앱개발] View Controller의 Life Cycle (0) | 2021.02.04 |
---|---|
[iOS 앱개발] MPNowPlayingInfoPropertyElapsedPlaybackTime 오류 해결 방법 (0) | 2021.02.02 |
[iOS 앱개발] Foreground, Background 알아보기 (0) | 2021.01.24 |
[iOS 앱개발] 네비게이션 컨트롤러에서 뷰들을 한 번에 pop하기 (0) | 2021.01.05 |
[iOS 앱개발] MPRemoteCommandCenter 사용하기 (0) | 2021.01.04 |
- Total
- Today
- Yesterday
- 테이블뷰
- 자료구조
- 동시성
- 알고리즘
- IOS
- 프로그래밍
- Swift
- 코딩테스트
- OSTEP
- 문법
- DP
- BFS
- 스위프트
- 아이폰
- 백준
- dfs
- OS
- Publisher
- mac
- Apple
- System
- Combine
- document
- design
- Xcode
- operating
- 앱개발
- pattern
- 코테
- operator
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |