이번엔 그리드 모양의 컬렉션 뷰를 만들어 볼 것이다. 어렵겠지만 일단 쫄지말고 도전! 👊
일단 생각을 해보자 어떻게 하면 그리드 모양을 만들 수 있을까? 🙄
한 줄에 몇개의 셀을 표현할지 결정하고, 그 셀들을 재사용해서 나타내주고, 그리드 모양이니까 셀 사이의 간격을 주면 될 것 같다!!
한 줄에 몇개의 셀을 표현할래? ➡️ 난 3개
셀 재사용은 어떻게 할껀데? ➡️ dequeueReusableCell을 사용할래
셀 사이의 간격은 어떻게 지정 할껀데? ➡️ delegate에서 minimumLineSpacingForSectionAt랑 minimumInteritemSpacingForSectionAt를 쓰면 될 것 같은데?
자 생각 다 끝났으면 고민하지말고 해보자 ㄱㄱ 👍
나는 내가 좋아하는 축구 팀인 리버풀 선수들 사진을 모아 놓은 갤러리를 만들어야겠다.
0. 더미 데이터 만들기
갤러리니까 간단하게 라벨은 제외하고 이미지 뷰만 사용할 것이기 때문에 더미 데이터는 이미지 에셋만 만들어 주면 된다.
1. 스토리보드로 컬렉션 뷰 구성하기
간단하다. 이미지만 쓸거니까! 컬렉션 뷰를 만들어주고 셀에 이미지 뷰를 넣어주면 된다. 당연히 오토레이아웃도 설정했다 !
2. ViewController에 CollectionView 연결하기
화면 구성을 마쳤으면 컬렉션 뷰를 뷰 컨트롤러에 연결해주면 된다. IBO로 연결 해주자.
import UIKit
class liverpoolGalleryUIViewController: UIViewController {
@IBOutlet weak var liverpoolGalleryCollectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
}
}
3. CollectionView를 구성할 cell 만들기
저번과 마찬가지로 나는 따로 관리하는 것을 좋아하기 때문에 (유지보수나, 재사용성 때문에?) 따로 셀을 관리할 파일을 만들어 주었다.
연결 끝 ~ 간단하다. 이제 셀을 구성해보자 ! 🤓
import UIKit
class liverpoolGalleryCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var liverpoolGalleryImageView: UIImageView!
}
일단 이미지뷰를 IBO를 이용해서 셀에 연결해주자.
import UIKit
class liverpoolGalleryCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var liverpoolGalleryImageView: UIImageView!
func printImage(_ imageName: String) {
liverpoolGalleryImageView.image = UIImage(named: imageName)
}
}
그리고 해당 객체에 데이터를 전달 할 함수를 만들어주자.
4. ViewController에서 CollectionView 표현하기
import UIKit
class liverpoolGalleryUIViewController: UIViewController {
@IBOutlet weak var liverpoolGalleryCollectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
liverpoolGalleryCollectionView.dataSource = self
liverpoolGalleryCollectionView.delegate = self
}
}
extension liverpoolGalleryUIViewController:UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 24
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "liverpoolGalleryCollectionViewCell", for: indexPath) as? liverpoolGalleryCollectionViewCell else {
return UICollectionViewCell()
}
let image = "liverpool_Img\(indexPath.item + 1)"
cell.printImage(image)
return cell
}
}
extension liverpoolGalleryUIViewController:UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: liverpoolGalleryCollectionView.bounds.width, height: 200)
}
}
일단 컬렉션 뷰한테 dataSource와 delegate를 제공 해주고 실행 해보자.
당연한 결과다. 아직 그리드를 위한 구성을 안했으니까.. 어떻게 하지 생각해볼까
한 줄에 몇개의 셀을 표현할래? ➡️ 난 3개
셀 재사용은 어떻게 할껀데? ➡️ dequeueReusableCell을 사용할래 ✅
셀 사이의 간격은 어떻게 지정 할껀데? ➡️ delegate에서 minimumLineSpacingForSectionAt랑 minimumInteritemSpacingForSectionAt를 쓰면 될 것 같은데?
일단 2번은 성공이고.. 첫번째 부터 해볼까? 세개의 셀을 표현해야하니까 셀의 너비와 높이를 계산해 줘야할 것 같은데 ..높이는 너비랑 똑같이 하면 되니까 패스 ! 이제 중요한 너비인데.. 너비는 콜렉션 뷰의 너비에서 3을 나눠주면 되지 않을까 ? 왜냐면 한 줄에 세개니까 .. 당연한데 음 예를들면 콜렉션 뷰의 너비가 60이라면 사진 하나당 너비가 20이면 한번에 3개를 표현 할 수 있으니까 ? 아무튼 그렇게 해보자
extension liverpoolGalleryUIViewController:UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = (liverpoolGalleryCollectionView.bounds.width) / 3
return CGSize(width: width, height: width)
}
}
아 뭔가 되긴 했는데 두 개씩 나오네.. 뭐가 문제지 확인 해봐야겠다.
일단 사이즈는 충분한 것 같은데 왜 가운데에 사진이 안들어갈까? 셀 사이의 간격을 줘야하나? 일단 그러면 셀 사이의 간격을 지정해보자. minimumLineSpacingForSectionAt랑 minimumInteritemSpacingForSectionAt를 이용하면 되니까 셀 사이의 간격을 1로 줘보자.
한 줄에 몇개의 셀을 표현할래? ➡️ 난 3개
셀 재사용은 어떻게 할껀데? ➡️ dequeueReusableCell을 사용할래 ✅
셀 사이의 간격은 어떻게 지정 할껀데? ➡️ delegate에서 minimumLineSpacingForSectionAt랑 minimumInteritemSpacingForSectionAt를 쓰면 될 것 같은데? ✅
extension liverpoolGalleryUIViewController:UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 1
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 1
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = (liverpoolGalleryCollectionView.bounds.width) / 3
return CGSize(width: width, height: width)
}
}
똑같다 !! 😡
좀 생각해보니까 셀 사이의 간격이 1이면, 그만큼 빼줘야하지 않을까?
그니까 3개의 셀을 한 줄에 놓으려면 셀 사이의 간격은 셀1 셀2 셀3 간격은 2개니까 저 간격 만큼을 빼줘야하지 않을까?
바로 ㄱㄱㄱㄱㄱ 뭔가 될 것 같음 . . 😎
한 줄에 몇개의 셀을 표현할래? ➡️ 난 3개 ✅
셀 재사용은 어떻게 할껀데? ➡️ dequeueReusableCell을 사용할래 ✅
셀 사이의 간격은 어떻게 지정 할껀데? ➡️ delegate에서 minimumLineSpacingForSectionAt랑 minimumInteritemSpacingForSectionAt를 쓰면 될 것 같은데? ✅
extension liverpoolGalleryUIViewController:UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 1
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 1
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let padding:CGFloat = 1
let width = (liverpoolGalleryCollectionView.bounds.width - padding*2)/3
return CGSize(width: width, height: width)
}
}
오 됐다 !!!! 사진이 비율이 이상하니까 이미지의 Content Mode를 Scale To Fill로 바꿔주고 간격을 좀 더 넓혀줘야겠다.
그리고 멋있게 다크모드로 바꾸면 ?
좋아좋아 오늘도 하나 배웠다. 🔥
그리드로 나타내려면 너비 계산만 잘 하면 된다 !
'Swift > UIkit' 카테고리의 다른 글
[UIkit] 오토 레이아웃 파헤치기 - 2 ⛏️ (0) | 2023.03.24 |
---|---|
[UIkit] 오토 레이아웃 파헤치기 - 1 ⛏️ (0) | 2023.03.24 |
[UIKit] CollectionView 간단한 예제로 공부해보기 (0) | 2023.03.23 |
[UIkit] CollectionView 알아보기 🔎 !! (0) | 2023.03.23 |
[UIkit] IBOutlet / IBAction (0) | 2023.03.20 |