# 프로젝트 매니저 STEP 2 추가 학습 내용
## :large_orange_diamond: NSCollectionLayoutContainer
> 레이아웃 컨테이너의 크기 및 콘텐츠 삽입에 대한 정보를 제공하는 데 사용되는 프로토콜
``` swift
@MainActor protocol NSCollectionLayoutContainer
```
### :small_orange_diamond: Overview
section provider에서 레이아웃 환경(NSCollectionLayoutEnvironment)의 컨테이너 프로퍼티를 사용하여 크기 및 콘텐츠 삽입과 같은 레이아웃의 컨테이너에 대한 정보를 가져온다.
레이아웃의 섹션을 렌더링하는 동안 컨테이너의 크기를 알면 레이아웃을 표시하는 방법을 결정하는 데 도움이 된다.
#### ★ 레이아웃 컨테이너란?
크기 및 콘텐츠 삽입과 같은 레이아웃의 속성
### :small_orange_diamond: NSCollectionLayoutEnvironment과 비교
#### `NSCollectionLayoutEnvironment`
- 컬렉션 뷰의 레이아웃 환경을 제공하는 프로토콜
- 컬렉션 뷰의 레이아웃에 영향을 주는 요소 포함
- 컬렉션 뷰의 컨텐츠 사이즈, traitCollection(세로 모드, 가로 모드) 등
- 레이아웃 환경을 사용하여 레이아웃이 표시되는 컨텍스트에 대한 정보를 제공하는 역할
- 크기 및 콘텐츠 삽입과 같은 레이아웃의 컨테이너에 대한 정보와 크기 클래스와 같은 환경 특성
#### `NSCollectionLayoutContainer`
- 컬렉션 뷰의 레이아웃 컨테이너를 나타내는 프로토콜
- 컬렉션 뷰의 크기와 콘텐츠 사이즈 등과 같은 정보를 포함
- 레이아웃 컨테이너의 크기와 속성을 제공하여 레이아웃 객체(NSCollectionLayoutSection, NSCollectionLayoutItem 등)의 크기와 위치를 계산하는 역할
---
## :large_orange_diamond: visibleItemsInvalidationHandler
> Instance Property
> layout cycle 전에 섹션의 아이템을 수정할 수 있도록 호출되는 클로저
``` swift
var visibleItemsInvalidationHandler: NSCollectionLayoutSectionVisibleItemsInvalidationHandler? { get set }
```
#### `NSCollectionLayoutSectionVisibleItemsInvalidationHandler`
``` swift
typealias NSCollectionLayoutSectionVisibleItemsInvalidationHandler = ([NSCollectionLayoutVisibleItem], CGPoint, NSCollectionLayoutEnvironment) -> Void
```
#### ★ NSCollectionLayoutVisibleItem
cell, supplementary view, decoration과 같이 섹션의 bounds 내에서 현재 보이는 아이템을 나타낸다.
### :small_orange_diamond: Discussion
컬렉션 뷰 레이아웃의 각 섹션에는 visible items invalidation handler가 있을 수 있다.
이 핸들러를 사용하여 해당 섹션의 범위 내에서 현재 표시되는 항목에 대해 사용자 지정 애니메이션을 수행한다.
핸들러는 항목 추가 또는 제거, 섹션 스크롤 또는 디바이스 회전과 같은 변경 사항으로 인해 해당 섹션에서 애니메이션이 발생할 때마다 각 레이아웃 사이클 전에 호출된다.
``` swift
let section = NSCollectionLayoutSection(group: group)
section.visibleItemsInvalidationHandler = { visibleItems, scrollOffset, layoutEnvironment in
// 눈에 보이는 item에 대해 애니메이션을 수행합니다.
}
```
-> 컬렉션 뷰 레이아웃이 갱신되면 해당 핸들러를 호출할 수 있게되는 것
---
## :large_orange_diamond: setCustomSpacing
> Stack view의 Instance Method
> 지정된 뷰 뒤에 사용자 지정 간격을 적용합니다.
``` swift
func setCustomSpacing(
_ spacing: CGFloat,
after arrangedSubview: UIView // spacing 적용할 `앞`의 뷰
)
```
### :small_orange_diamond: 예시
특정 spacing을 다르게 하고 싶은 경우 사용한다.
예를 들어 label1, label2, label3을 서브 뷰로 가진 스택 뷰가 있을 때
label2, label3에만 spacing을 10주고 싶다면 아래와 같이 설정할 수 있다.
``` swift
//...
stackView.setCustomSpacing(10, after: label2)
//...
```