티스토리 뷰

반응형

이번 글에서는 저번 글에 이어 컬렉션 뷰에서 Flow Layout을 사용하는 방법에 대하여 알아보려고 한다. 해당 정보는 공식 문서를 참고했다.

 

Apple Developer Document - Using the Flow Layout

Using the Flow Layout

컬렉션 뷰에서 UICollectionViewFlowLayout 클래스의 레이아웃 객체를 사용해서 항목들을 정렬할 수 있다. Flow 레이아웃은 선 기반 레이아웃을 구현한다. 이 말은 flow 레이아웃이 셀들을 임의의 선을 그려 그 위에 배치한다고 보면 된다. 만약 임의의 선에 셀들이 다 차면 새로운 선을 그려서 계속 배치해 나간다.

 

위의 그림에서는 세로로 스크롤되는 flow 레이아웃의 모습을 보여준다. 여기서 각각의 선들이 가로로 그려지고 그 위에 셀들을 채워 넣는 구조이다. 만약 그려진 선에 셀이 가득 차면 아래에 새로운 선을 그려 셀을 계속 채워나간다. 위의 그림처럼 셀들은 Header, Footer로 둘러싸일 수도 있다.

 

Flow 레이아웃을 사용하여 grid(격자무늬)를 구현할 수도 있지만 그것보다 더 많은 모양으로도 구현할 수 있다. 선형 레이아웃의 아이디어는 다양한 디자인에 적용할 수 있는데 예를 들어 grid를 사용하지 않고 하나의 행만 만들어 스크롤로 이동되는 셀들을 나열할 수도 있다.

코드로 만드는 방식으로는 Xcode에서 Interface Builder를 사용하여 flow 레이아웃을 만들 수 있다. 이러한 flow 레이아웃의 구성 단계는 다음과 같다.

 

  1. Flow 레이아웃 객체를 작성하고 컬렉션 뷰에 이를 할당한다.
  2. 셀의 width, height를 정한다.
  3. 선과 항목들의 간격을 설정한다. (Optional)
  4. 섹션에 header, footer를 넣고 싶다면 이것들의 크기를 지정한다.
  5. 레이아웃의 스크롤 방향을 설정한다.

여기서 반드시 진행해야하는 부분은 셀의 너비와 높이를 정하는 것이다. 그렇지 않은 경우 셀의 너비와 높이가 0이 되어 보이지 않게 된다.

Customizing the Flow Layout Attributes

Flow 레이아웃 객체는 앱에 있는 콘텐츠의 모양을 구성하기 위해 여러 프로퍼티를 갖는다. 이러한 프로퍼티를 설정하면 레이아웃의 모든 항목에 동일하게 적용된다. 예를 들어 flow 레이아웃 객체의 itemSize 프로퍼티를 사용하여 셀의 크기를 설정하면 모든 셀이 같은 크기를 갖게 된다.

 

항목의 간격이나 크기를 동적으로 변경하려면 UICollectionViewDelegateFlowLayout 프로토콜의 메서드를 사용하면 된다. 컬렉션 뷰에 할당한 델리게이트 객체와 동일한 곳에 이러한 메서드를 구현하면 된다. 메서드가 구현되면 flow 레이아웃 객체는 고정된 값을 사용하는 것이 아닌 메서드를 호출하고 반환된 값을 사용하게 된다.

Specifying the Size of Items in the Flow Layout

만약 컬렉션 뷰의 모든 항목이 같은 크기를 갖게 하고 싶다면 itemSize 프로퍼티에 원하는 너비와 높이 값을 할당하면 된다. 이 방법은 크기가 변하지 않는 콘텐츠에 대한 레이아웃 객체를 구성하는 방법 중 가장 빠른 방법이다.

 

셀에 대해 각자 다른 크기를 지정하려면 컬렉션 뷰 델리게이트에 collectionView(_ layout: _ sizeForItemAtIndexPath:) 메서드를 구현하면 된다. Index path 정보를 사용하여 각 위치에 있는 셀의 크기를 설정할 수 있다.

 

위의 그림과 같이 항목을 선에 그릴 땐 가운데를 맞춘다. 전체 셀의 너비 혹은 높이는 가장 큰 항목에 의해 결정된다. 이렇게 셀의 크기가 다르게 되면 줄마다 항목 수는 변할 수 있다.

Specifying the Space Between Items and Lines

Flow 레이아웃을 사용하여 같은 줄에 있는 항목들의 간격이나 줄 사이의 간격을 지정할 수 있다. 여기서 설정하는 간격은 최소 간격으로 배치하는 방법에 따라 지정한 값보다 큰 값으로 증가시킬 수도 있다.

 

레이아웃 중 flow 레이아웃 객체는 행에 더 이상 항목을 넣을 수 없을 때까지 항목을 추가한다. 여기서 항목들의 크기가 같으면 최소로 설정한 간격을 지킬 수 있지만 항목들의 크기가 다르다면 실제 간격이 다를 수 있다.

 

위의 그림은 항목들의 크기가 다를 경우에 발생하는 간격에 대해 나타낸 그림이다. 위의 그림처럼 항목들의 크기가 모두 다르면 각각의 간격을 동일하게 하기 위해 설정한 간격과 다르게 나타날 수도 있다.

 

행들의 간격의 경우 항목들의 간격과 동일한 방법을 사용한다. 모든 항목의 크기가 동일한 경우엔 최소로 설정한 줄 간격을 지키며 행의 모든 항목은 다음 행의 항목과 동일한 간격을 유지한다.

 

하지만 위의 그림처럼 행 속에 있는 항목들의 크기가 다를 경우 항목들의 간격이 서로 다를 수 있다. 이 경우 행마다 스크롤 방향의 크기가 가장 큰 항목을 선택하고 그 항목들 사이의 간격을 최솟값으로 설정한다.

 

다른 flow 레이아웃 속성들과 마찬가지로 고정된 간격을 설정하거나 동적으로 값을 바꿀 수 있다. 행과 항목들의 간격은 섹션별로 처리되는데 그렇기 때문에 행과 항목 간 간격은 주어진 섹션의 모든 항목에는 동일하지만 다른 섹션의 항목들과는 다를 수 있다. Flow 레이아웃 객체의 minimumLineSpacing, minimumInteritemSpacing 프로퍼티나 컬렉션 뷰 델리게이트의 collectionView(_ :layout, _ :minimumLineSpacingForSectionAtIndex), collectionView(_ :layout,_ :minimumInteritemSpacingForSectionAtIndex) 메서드로 간격을 설정할 수 있다.

Using Section Insets to Tweak the Margins of Your Content

섹션을 삽입하는 것은 셀 레이아웃에 사용 가능한 공간을 조정하는 것이다. 섹션의 header, footer 사이에 삽입을 할 수 있다.

 

위의 그림은 수직으로 움직이는 flow 레이아웃에서 삽입된 내용이 일부 내용에 미치는 영향을 보여준다. 삽입으로 인해 셀 레이아웃에 사용할 수 있는 공간의 양이 줄어들기 때문에 지정된 행의 셀 수를 제한할 수 있다. 비 스크롤 방향으로 삽입을 지정하면 각 줄의 공간을 제한할 수 있다.

Knowing When to Subclass the Flow Layout

서브 클래싱 없이도 flow 레이아웃을 잘 쓸 수 있지만 사용해야 할 경우도 있다. 다음 표를 참고해서 사용하는 상황을 알아보자.

Scenario Subclassing tips
레이아웃에 새로운 보충 뷰나 장식 뷰를 추가하고 싶을 때 기본 Flow 레이아웃 클래스는 섹션의 Header, Footer만 지원하고 장식 뷰는 지원하지 않는다. 추가적인 보충 뷰나 장식 뷰를 만들고 싶다면 최소한 다음 메서드들은 오버라이드 해야한다.
Flow 레이아웃에서 반환되는 레이아웃 속성을 조정하고 싶을 때 layoutAttributesForElementsInRect() 메서드와 레이아웃 속성을 반환하는 모든 메서드를 오버라이드 해야한다. 메서드 구현은 super로 호출하여 상위 클래스가 제공한 속성을 수정 한 다음 반환해야한다.
셀과 뷰에 새로운 레이아웃 속성을 추가하고 싶을 때 UICollectionViewLayoutAttributes 클래스의 서브클래스를 만들고 레이아웃 정보를 나타내는 데 필요한 특성을 추가한다.

UICollectionViewFlowLayout 클래스를 서브클래싱하여 layoutAttributesClass() 메서드를 오버라이드 해야한다. 해당 메서드는 직접 만든 클래스를 반환해야한다.

layoutAttributesForElementsInRect(), latoutAttributesForItemAtIndexPath() 메서드 및 레이아웃 속성을 반환하는 다른 메서드를 오버라이드해야한다. 직접 정의한 속성 값들을 설정해 주면 된다.
삽입 또는 삭제되는 항목의 초기 또는 최종위치를 지정하고 싶을 때 기본적으로는 삽입 또는 삭제되는 항목에 대해 간단한 fade 애미네이션이 생성된다. 사용자 정의 애니메이션을 만들려면 다음 방법 중 일부나 정부를 오버라이드 해야한다.

이러한 메서드를 재정의 하는 경우 PrepareForCollectionViewUpdates(), finalizeCollectionViewUpdates() 메서드도 오버라이드 하는게 좋다. 이러한 방법을 사용하여 현재 삽입 삭제될 항목을 추적할 수 있다.

 

처음부터 layout을 직접 만드는 것이 좋을 수도 있다. Flow 레이아웃은 다양한 종류의 레이아웃에 사용할 수 있는 동작들을 직접 만들 수 있도록 해준다. 이러한 것은 최적화가 되어있기 때문에 효율적이고 사용하기 쉽다. 하지만 이러한 것들은 의미가 있는 상황이 있기 때문에 레이아웃을 직접 작성하지 말란 것은 아니다. Flow 레이아웃은 스크롤 방향이 한 방향이므로 레이아웃이 화면 경계보다 더 크다면 레이아웃을 직접 정의하는 것이 더 적합하다. Gird 또는 선 기반 레이아웃이 아니거나 레이아웃 내의 항목들이 너무 자주 이동하게 되면 레이아웃을 직접 만드는 것도 좋은 방법이다. 이렇게 레이아웃을 직접 만드는 방법에 관한 내용은 Creating Custom Layouts를 참고하자.

반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
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
글 보관함