바로 전에 CollectionViewFlowLayout에 대해 알아보았다. 역시 단순히 알아보는 것만으로는 제대로 사용하기 힘들다. 직접 사용해보며 익혀보도록 하겠다.
CollectionView도 처음 사용해보기 때문에, 단계별로 함께 구현해보자.
스토리보드에서 컬렉션뷰를 드래그하여 추가하고, 헷갈리지 않도록 백그라운드 컬러를 변경한다.
셀 내부에는 두 개의 Label을 세로로 배치하고, 이미지와 같이 제약조건을 설정한다.
셀의 식별자는 "Cell"로 설정한다.
컬렉션 뷰는 ViewConroller에 연결하였고, 컬렉션뷰 셀에 대한 설정은 myCollectionView파일에서 연결한다.
class ViewConrlloer: UIViewController {
@IBOutlet weak var myCollectionView: UICollectionView
}
class myCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var firstLabel: UILabel!
@IBOutlet weak var secondLabel: UILabel!
}
UICollectionvViewDataSource 프로토콜을 채택하여 컬렉션뷰를 사용할 준비를 한다. 필수 메서드를 구현해야 하는데, Fix를 누르면 쉽게 추가할 수 있다. dataSource를 self로 지정하는 것을 잊지 말자.
override func viewDidLoad() {
super.viewDidLoad()
myCollectionView.dataSource = self
}
간단한 예시를 통해 컬렉션뷰의 동작을 확인해보자.
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 15
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath) as? MyCollectionViewCell else {
fatalError("MyCollectionViewCell로 캐스팅할 수 없음")
}
cell.firstLabel.text = "강아지"
cell.secondLabel.text = "고양이"
return cell
}
기본 설정의 컬렉션뷰를 이용해보았다.
이제 Flow Layout을 적용해보겠다.
let flowLayout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
myCollectionView.collectionViewLayout = flowLayout
Flow Layout을 적용했지만, 아직 기본 속성에 대한 값이 할당되지 않아서 아래 이미지와 같이 보인다.
sectionInset 속성을 사용하여 여백을 설정할 수 있다.
flowLayout.sectionInset = UIEdgeInsets.init(top: 50, left: 50, bottom: 50, right: 50)
minimumLineSpacing, minimumInteritemSpacing 속성을 이용하여 아이템 간의 간격을 설정할 수 있다.
flowLayout.minimumLineSpacing = 50
flowLayout.minimumInteritemSpacing = 50
itemSize 속성을 이용하여 모든 아이템의 크기를 동일하게 설정 가능하다.
flowLayout.itemSize = CGSize(width: 100, height: 100)
그런데 만약 특정 아이템의 내부 라벨의 길이가 더 길어야 한다면 어떻게 할까?
특이하고 긴 이름의 동물들을 찾다가 "비명을 지르는 털이 많은 아르마딜로"라는 이름의 동물을 찾았다. 딱이다
코드를 조금 수정해보았다. 3번째 마다 firstLabel의 text를 "비명을 지르는 털이 많은 아르마딜로" 적용해보겠다.
let itemCount = indexPath.item + 1
if itemCount % 3 == 0 {
cell.firstLabel.text = "비명을 지르는 털이 많은 아르마딜로"
cell.backgroundColor = .blue
} else {
cell.firstLabel.text = "강아지"
}
cell.secondLabel.text = "고양이"
return cell
의도한대로 나오지 않는다.
아이템의 사이즈를 다르게 하고 싶다면 UICollectionViewDelegateFlowLayout의 collectionView:layout:sizeForItemAtIndexPath 메서드를 활용할 수 있다.
extension ViewController: UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let itemCount = indexPath.item + 1
if itemCount % 3 == 0 {
return CGSize(width: 300, height: 100)
}
return CGSize(width: 100, height: 100)
}
}
3배수 아이템의 크기를 크게 설정하였다.
CollectionViewFlowLayout를 활용하는 방법을 알아보았다. 이를 통해 UI를 다양하게 구성할 수 있었다.
iOS 13에서 소개된 새로운 컬렉션 뷰 레이아웃인UICollectionViewCompositionalLayout 여러 종류의 섹션과 아이템 배치를 조합하여 복잡한 레이아웃 구조를 쉽게 구현할 수 있게 해준다. CollectionViewFlowLayout 만큼 자주 사용되기 때문에 다음에는 UICollectionViewCompositionalLayout에 대해서 알아보겠다.