Layer-Tree Hierarchy
OSXDEV
Core Animation Programming Guide로 이동
레이어는 뷰 계층구조를 만드는 다른 뷰들에 대한 컨테이너로서 동작한다. 이 장에서는 레이어 계층구조와 계층구조 내에서 레이어를 다루는 법을 설명한다.
목차 |
[편집] Layer-Tree 계층이란?
레이어-트리는 코코아의 뷰 계층구조의 코어 애니메이션 판이다. NSView가 슈퍼뷰와 서브뷰를 가지는 것과 같이, 코어 애니메이션 레이어는 슈퍼레이어와 서브레이어를 가진다. 레이어-트리는 뷰 계층구조와 같이 많은 장점을 제공한다:
- 복잡한 인터페이스는 모놀리딕하고 복잡한 서브클래싱이 필요없이, 단순한 레이어들의 집합으로 가능하다. 레이어들은 그들의 복잡한 합성 능력때문에 이러한 '쌓아올리기'에 적합하게 만들어졌다.
- 각각의 레이어들은 슈퍼레이어의 좌표계에 상대적으로 그 자신의 좌표계를 선언한다. 레이어가 트랜스폼 되면, 그 서브레이어들은 그 안에서 트랜스폼 된다.
- 레이어-트리는 동적이다. 어플리케이션이 동작하면서 재설정될 수 있다. 레이어가 만들어져서 다른 레이어에 첫번째 혹은 그 이상의 순차에 서브레이어로 더해질 수 있고, 레이어 트리에서 제거될 수도 있다.
[편집] 뷰에 레이어를 디스플레이 하기
코어 애니메이션은 윈도우에 실제로 디스플레이 하는 방법을 제공하지 않는다. NSView 인스턴스내에 포함되어야 한다. 뷰와 짝지어지면, 뷰가 아래에 놓인 레이어로 이벤트-처리를 제공해 주고, 레이어가 디스플레이할 내용을 제공한다.
NSView 인스턴스는 그것이 레이어를 가질 수 있도록 설정된다. 레이어 계층의 루트 레이어를 디스플레이 하기 위해서, Listing 1처럼 뷰의 레이어를 설정하고 뷰가 레이어를 사용하도록 조정한다.
Listing 1 레이어를 뷰에 넣기
//theView는 윈도우안에 있는 뷰이다 //theRootLayer는 레이어 계층에서의 루트 레이어 이다. [theView setLayer: theRootLayer]; [theView setWantsLayer:YES];
[편집] 계층에 레이어를 추가하고 제거하기
레이어 인스턴스를 단순히 인스턴스화 하는 것만으로는 레이어-트리에 넣을 수 없다. 표1에 설명된 메소드들을 이용해서 레이어 트리에 더하고, 삽입하고 제거해야 한다.
표1. 레이어 트리 관리 메소드들
| 메소드 | 결과 |
|---|---|
| addSublayer: | receiver의 서브레이어 배열에 레이어를 더한다 |
| insertSublayer:atIndex: | 레이어를 receiver의 서브레이어로서 지정된 인덱스에 삽입한다 |
| insertSublayer:below: | 레이어를 receiver의 서브레이어 배열에, 지정된 서브레이어 아래로 삽입한다 |
| insertSublayer:above: | 레이어를 receiver의 서브레이어 배열에, 지정된 서브레이어 위로 삽입한다 |
| removeFromSuperlayer | receiver를 서브레이어 어레이에서 또는 receiver의 수퍼레이어의 마스크 프라퍼티에서 제거한다 |
| replaceSublayer:with: | receiver의 서브레이어들의 배열을 지정된 새로운 레이어로 대체한다 |
레이어의 서브레이어들을 레이어 배열을 이용해서 설정할 수 있으며, 슈퍼레이어의 서브레이어 프라퍼티에도 원하는 것을 설정할 수 있다. 레이어 오브젝트들로 구성된 배열로 서브레이어 프라퍼티를 설정할 때, 각각의 레이어들에 대한 슈퍼레이어가 nil로 설정되어있는지 확인해야 한다.
기본적으로, 화면에 보이는 레이어-트리로부터 레이어를 삽입하고 제거하면 애니메이션을 촉발한다. 어떤 레이어가 서브레이어로 더해지면 부모 레이어로부터 kCAOrderIn 액션 아이덴티파이어가 촉발되어 애니메이션이 리턴된다. 레이어가 어떤 레이어의 서브레이어로부터 제거되면 부모 레이어로부터 kCAOrderOut 액션 아이덴티파이어가 촉발되어 애니메이션이 리턴된다. 서브레이어에서 레이어를 변경하는 것은 부모 레이어로부터 kCATransition 액션 아이덴티파이어가 촉발되어 애니메이션이 리턴된다. 레이어-트리를 수정할 때 애니메이션을 동작하지 않도록 하거나 액션 인식자에 의해 사용되는 애니메이션을 바꿀 수 있다.
[편집] 레이어를 재배치하고 크기조절하기
레이어가 만들어지고 나면, 레이어의 평면 프라퍼티를 값을 변경함으로서 간단하게 프로그래밍적으로 이동하고 크기조절할 수 있다: frame, bounds, position, anchorPoint 혹은 zPosition.
레이어의 needsDisplayOnBoundsChange 프라퍼티가 YES라면, 레이어의 컨텐트는 레이어의 바운드가 변경될 때 재 캐쉬 된다. 기본적으로 needsDisplayOnBoundsChange 프라퍼티는 NO이다.
기본적으로, frame, bounds, position, anchorPoint 그리고 zPosition 프라퍼티는 레이어가 새로운 값으로 애니메이트하도록 한다.
[편집] 레이어 자동크기조절
CALayer는 슈퍼레이어가 움직이거나 크기조절되면 자동적으로 서브레이어를 움직이고 크기조절하는 메카니즘을 제공한다. 많은 경우 레이어가 어플리케이션에 유사한 기능을 제공하는, 간단한 자동 크기조절 마스크를 설정한다.
레이어의 자동크기조절 마스크는 CAAutoresizingMask 상수와 레이어의 qutoresizeMask 프라퍼티를 비트 OR 연산을 한 결과값에 의해 지정된다. 표2는 마스크 상수와 각각이 레이어의 크기조절 비헤비어에 어떻게 영향을 미치는지 보여준다.
표2. 자동크기조절 마스크 값과 설명
| 자동 크기조절 마스크 | 설명 |
|---|---|
| kCALayerHeightSizable | 슈퍼레이어의 높이에 따라 레이어의 높이가 비례해서 변하거나 레이어의 높이는 슈퍼레이어에 상대적으로 변하지 않는다. |
| kCALayerWidthSizable | 슈퍼레이어의 너비에 따라 레이어의 너비가 비례해서 변하거나 레이어의 너비는 슈퍼레이어에 상대적으로 변하지 않는다. |
| kCALayerMinXMargin | 슈퍼레이어의 너비에 따라 레이어의 왼쪽 면이 비례해서 위치조정되거나 레이어의 왼쪽면은 슈퍼레이어에 상대적으로 동일한 위치를 유지한다. |
| kCALayerMinYMargin | 슈퍼레이어의 높이에 따라 레이어의 위쪽 면이 비례해서 위치조정되거나 레이어의 위쪽면은 슈퍼레이어에 상대적으로 동일한 위치를 유지한다. |
| kCALayerMaxYMargin | 슈퍼레이어의 너비에 따라 레이어의 아래쪽 면이 비례해서 위치조정되거나 레이어의 아래쪽면은 슈퍼레이어 상대적으로 동일한 위치를 유지한다. |
예를 들어, 한 레이어가 슈퍼레이어의 좌하단 모서리를 유지하려고 한다면, kCALAyerMaxXMargin | kCALayerMaxYMargin을 사용한다. 축을 따라 하나 이상의 방향으로 변동가능하다면, 크기조정 양은 그들 사이에 동일하게 분배된다. 그림 1은 상수값의 위치에 대해 그림으로 설명한다.
위 상수들 중 하나가 생략되었다면, 그 방향의 레이어 레이아웃은 고정되는 것이다; 상수가 마스크에 포함된다면, 그 방향으로 레이어의 레이아웃은 유동적이다.
서브클래스는 레이어의 자동크기조절 비헤비어를 커스터마이즈 하기 위해 CALayer의 resizeSublayersWithOldSize:와 resizeWithOldSuperlayerSize:를 오버라이드 할 수 있다. resizeSublayerWithOldSize: 메소드는 레이어의 바운드 프라퍼티가 변하면 자동적으로 발생하며, 각각의 서브레이어에 resizeWithOldSuperlayerSize: 메세지를 보낸다. 각각의 서브레이어는 원해의 바운드 사이즈와 새 사이즈를 비교해서 자동크기조절 마스크에 따라 그 위치와 크기를 조정한다.
[편집] 서브레이어 클리핑
코코아 뷰의 서브 뷰들이 부모 뷰의 바운드 바깥에 자리잡고 있으면, 뷰들은 부모 뷰에 의해 잘려나간다. 레이어는 부모 레이어에 대한 상대적인 위치에 상관없이, 서브 레이어들이 전체를 디스플레이 할 수 있도록 이 제한을 해제할 수 있다.
레이어의 masksToBounds 프라퍼티는 부모에 의해 서브레이어들이 클리프 될 것인지를 결정한다. masksToBounds 프라퍼티의 기본값은 부모에 의해서 클리프 되는 것을 방지하는 NO이다. 그림 2는 layerA의 masksToBounds 설정의 결과가 layerB와 layerC의 디스플레이에 어떻게 영향을 끼치는 지 보여준다.






