xxo' TIL/WIL

IOS/UIKit

[UIKit] mini project AppleFrameworks(UICollectionView)

xxoxec 2025. 8. 14. 17:05
UIKit의 UICollectionView를 이용해 iOS에서 실제 그리드와 리스트를 연습하고 리스트 뷰 구현하기. AppleFrameworks는 컬럼이 3개인 멀티 컬럼 그리드 뷰를 보여주고 상단 내비게이션 바가 있는 앱으로, 해당 미니 프로젝트에서 뷰 구성요소로 이미지, 이름이 필요한데 CollectionView를 사용하여 이미지, 레이블을 사용하여 넣어준다. UICollectionView를 이용한 리스트 및 그리드 개발을 위한 3가지 핵심인 Data / Presentation / Layout를 사용하여 AppleFrameworks를 보여주는 간단한 앱이다. 해당 mini project는 아이폰16으로 설정.

 

 

mini project AppleFrameworks

 

 

ViewController부터 만들어서 스토리보드에 연결하고 Storyboard ID를 동일하게 넣어준다.

Storyboard에서 + 버튼을 통해 CollectionView를 넣어주고 Ctrl(⌃) 누른 상태에서 상위 뷰에 마우스를 끌어 오토레이아웃 constraints를 정해준다. constraints 설정 시 Shift(⇧) 누르면서 선택하면 다중선택 가능.

CollectionView 오토레이아웃 constraints설정

 

이번 미니 프로젝트의 디자인은 간단하게 이미지와, 이름이 필요하므로 이미지와 레이블을 넣어준 후 오토레이아웃 설정을 한다.

이미지 같은 경우 오토레이아웃 시 이미지를 1:1로 만들고, Leading, Top, Trailing을 부모뷰에 맞게 붙여주도록 설정.

이미지 같은 경우 오토레이아웃 시 이미지를 1:1로 만들고,  Leading , Top,  Trailing을 부모뷰에 맞게 설정

하지만 이렇게 설정 시 위치와 넓이는 정해졌지만, 높이가 정해져 있지 않기 때문에 이미지뷰에서  Ctrl(⌃) 누른 상태에서 옆으로 끌어 Aspect Ratio를 1:1로 설정해 준다.

Aspect Ratio를 1:1로 설정

 

레이블의 이름과 크기 등을 설정해 주고 수직방향으로 거리를 만들어준다. 나머도 부모뷰에 맞춰 설정.

레이블 오토레이아웃 설정

 

텍스트의 두줄 설정 시 Ctrl(⌃) 누른 상태에서 Enter(↵)를 누르면 두줄로 표현이 가능하다.

Ctrl(⌃) 누른상태에서  Enter(↵)를 누르면  두줄로 표현이 가능

 

컬렉션 뷰셀에 필요한 프레임워크 각각에 표현할 커스텀 셀을 만들어 스토리보드에 지정해 준다.

셀은 재사용되므로 반드시 필요한 구분자인 Identifier에도 이름을 넣어준다.

커스텀 셀을 스토리보드에 지정 및 Identifier 설정

 

코드에 커스텀셀의 이미지와 레이블 연결해 주기.

이미지와 레이블 연결

 

프레임워크 데이터를 받아서 셀을 업데이트해 줄 메서드 추가.

메소드 추가.

 

Collection View를 해당 ViewController에 연결하고 데이터를 가져온 후,

Collection View를 표현하기 위해서 Data / Presentation / Layout 에 대해서 정의해 준다.

Collection View를 해당 ViewController에 연결
Data / Presentation / Layout
Data / Presentation / Layout

 

실제로 시뮬레이터 시 크래시가 발생하는데 해당 부분은 아래에 설명.

크래시 발생

 

시뮬레이터로 돌렸을 시 해당 이미지 등이 업데이트가 되지 않은 것을 확인할 수 있고 interItemSpacing이 의도치 않은 곳에 들어간 것을 명시적으로 각 아이템들 간의 좌우, 위아래 간격 등을 설정.

업데이트가 되지 않은 것을 확인 및  interItemSpacing 확인
InteritemSpacing, LineSpacing 설정

 

실제로 데이터를 세팅하게끔 코드 작성.

데이터 세팅 코드

 

다크모드 설정 : Features > Toggle Appearance 또는 Cmd(⌘) + Shift(⇧) +

Features > Toggle Appearance
Cmd(⌘) +  Shift(⇧) +  A 다크모드 설정

 

내비게이션 바를 포함하기

내비게이션 바는 내비게이션 뷰 컨트롤러를 만들어서 내비게이션 바를 포함시킬 수 있다.

내비게이션 뷰 컨트롤러는 앱을 사용하다 보면 여러 UI뷰컨트롤러가 있는데 뷰 컨트롤러 간의 네비게이팅을 도와준다.

스토리보드 > Editor > Embed In > Navigation Controller

스토리보드 > Editor > Embed In > Navigation Controller

 

내비게이션 바에서 타이틀 설정

Prefers Large Titles를 체크해 주는데 요즘의 많은 애플 제품 앱들은 이 부분이 적용된 것을 확인할 수 있다. (예: 애플뮤직)

내비게이션 아이템의 타이틀을 변경. 시뮬레이터를 돌려볼 시 스크롤을 하면 내비게이션 영역에 타이틀이 커져있었다가 작게 작아져서 들어가는 것을 확인할 수 있다. Prefers Large Titles 체크 해제 시 역시 영역 부분이 작게 들어가는 것을 확인할 수 있다.

 Prefers Large Titles

 

스크롤 시 내비게이션 영역에 블러 처리 및 하단 스크린 엣지 처리하기.

Collection View의 오토레이아웃을 살펴보면 Bottom과 Top 같은 경우에는 Safe Area라고 해서 아이폰의 경우 노치나 홈버튼이 없어지면서 스크린이 더 넓어졌는데, 어떤 콘텐츠를 확실히 보장되고, 보여줘야 하는 영역을 지정해 줘야 하므로 이 부분이 Safe Area라고 지정되어 있다. 이번 mini project의 경우 Safe Area 말고 상위 뷰를 투명하게 해서 화면이 더 넓게 보이게 하기 위해 블러처리를 하기 위해 오토레이아웃을 수정하는데, Bottom을 Superview로 설정하고,  Safe Area를 0으로 설정해 끝까지 지정해 준다. Top도 같은 방식으로 설정.

스크롤 시 내비게이션 영역에 블러 처리 및 하단 스크린 엣지 처리
스크롤 시 내비게이션 영역에 블러 처리 및 하단 스크린 엣지 처리

 

아이템들 간 좌우의 여백을 코드로 설정. 

Hierarchy로 확인해 보면 스크린에 바짝 붙어 좌우 여백이 없는 것을 확인할 수 있는데 이 부분을 contentInset으로 여백을 설정.

패딩을 contentInset으로 넣어주면서 셀 사이즈를 코드로 정했던 부분들이 Inset을 고려해서 계산한 코드가 아니기 때문에 코드도 수정.

Hierarchy로 확인 후 시뮬레이터 확인
contentInset으로 여백 설정
Inset을 고려 후 코드 수정

 

Collection View의 사이즈를 정하기 위해서 Estimate Size를 None로 설정해 줬었는데, 이 부분은 실제로 코드로 설정할 수도 있다.

estimatedItemSize는 자동으로 시스템 계산되는 부분을 요청한다는 의미로 생각하면 쉬운데  임의로 셀 사이즈를 코드로 정해줬었던 부분 중 일부분은 자동으로 계산이 되는데 이 부분을 하지 말라고 코드로 작성 표현 한 것이다. 이 부분에 관한 설명은 해당 아래 참고.

estimatedItemSize 를 zero로 코스 설정

 

클릭했을 때 반응하는 부분(예: 상세뷰)을 알기 위해서는 클릭이 되는 걸 알아야 하는데, 이 부분은 선택된 아이템들에 대해 didSelectItemAt을 통해 확인해 볼 수 있다.

didSelectItemAt

 

Collection View 자체는 데이터를 표현하는데 집중하고 있고 그 외 어떻게 데이터를 표현할지, 그런 부분들을 프로토콜로 만들어놓고 다른 위임자를 통해 활용한다. detaSource는 데이터와, 셀 프리젠테이션소스와 관련해서 쫌 더 구체적으로 위임하고, delegate 그 외 여러 위임들을 하게 되는데, 선택된 아이템들에 대한 확인이나, 레이아웃관련된 위임등을 할 수 있다.

 

추가로 셀 아이템을 두 줄 또는 네 줄로 만들어 보기 및 글자 잘림 시 폰트 사이즈에 맞게 수정.

셀 아이템 두줄 및 네줄로 바꿔보기

 

셀이 스토리보드에서 깨어날 때 이름 자체를 줄 하나로 표시하도록 설정하고, adjustsFontSizeToFitWidth을 통해 폰트 사이즈를 설정해 놓은 폰트 사이즈가 있지만 셀이 맞게 코드로 조정할 수 있다.

adjustsFontSizeToFitWidth

 

navigationController를 이용하여 코드로도 이름을 바꿔줄 수 있다.

navigationController

 

 

 


 

 

 

오류1 : The collection view's data source returned a cell without a reuseIdentifier

크래시 발생

UICollectionView에서 dequeueReusableCellWithReuseIdentifier 또 dequeueConfiguredReusableCellWithRegistration을 사용하여 재사용 식별자가 있는 셀을 가져오지 않아 발생한 오류라고 하며, UICollectionView의 데이터 소스 메서드에서 셀을 반환할 때, 반드시 dequeueReusableCell 관련 메서드를 사용하여 재사용 식별자와 함께 셀을 가져와야 한다고 한다.

UICollectionView는 셀을 효율적으로 관리하기 위해 재사용 큐(reuse queue)를 사용한다. 화면에서 보이지 않게 된 셀을 메모리에서 제거하는 대신 재사용 큐에 보관했다가, 새로운 셀이 필요할 때 재사용 큐에서 꺼내어 재사용한다. 이때 각 셀의 종류를 구분하는 것이 바로 reuseIdentifier이다.

 

reuseIdentifier 설정

 

오류2 : 멀티 컬럼이 아닌 싱글 컬럼으로 출력 > estimatedItemSize 설정

estimatedItemSize 설정

 

미니 프로젝트 중 시뮬레이터를 돌려보면 셀들이 멀티 컬럼으로 출력되지 않고 싱글 컬럼으로 출력되는 것을 확인되었다. 처음엔 코드를 잘못 작성하거나 오토레이아웃이 잘못 설정되어 있는지 확인해 보았으나, 정확한 이유를 찾지 못했다. 결론적으로는 오토레이아웃 설정 시 설정을 변경해줬어야 했는데 이 부분을 해주지 않아서 생긴 오류였다. 나중에 코드로도 작성.

코드로도 작성 가능

구글링 해본 결과 'estimatedItemSize'는 컬렉션 뷰(UICollectionView)나 테이블 뷰(UITableView)와 같은 iOS UI 구성 요소에서 사용되는 속성이라고 하며, 이 속성은 화면에 표시될 셀(cell)의 대략적인 크기를 설정하는 데 사용된다.

위 본문에 언급했듯이 estimatedItemSize는 자동으로 시스템 계산되는 부분을 요청한다는 의미로 생각하면 쉬운데  임의로 셀 사이즈를 코드로 정해줬었던 부분 중 일부분은 자동으로 계산이 되는데 이 부분을 하지 말라고 나중에 코드로 작성했었다. 쉽게 설정으로도 가능하지만, 셀 사이즈를 정할 때 자동으로 계산이 필요한 부분이 아니라면 코드로 작성하고 확인할 때가 편할 때가 있으므로, 코드로 작성하는 부분도 알아두면 좋다.

 

참고 : https://developer.apple.com/documentation/uikit/uicollectionviewflowlayout/estimateditemsize

 

estimatedItemSize | Apple Developer Documentation

The estimated size of cells in the collection view.

developer.apple.com