- Table View에 비해 데이터 나열이 자유롭기 때문에 많은 아이템을 보여주는 상황에서 사용
- 수평, 수직 나열 방향을 정할 수 있음
- Collection View Cell을 이용해서 표현
- UICollectionViewLayout : Layout에 대해서 전문적으로 관리하는 객체가 필요
- UICollectionViewLayout을 상속받아서 나만의 Layout을 만들 수 있음
- UICollectionViewFlowLayout : 기본적으로 제공하는 Layout 객체
- 1행 안에 여러 개의 열을 표현하고 싶을 때 사용
실습
1-1, Collection VIew 추가
1-2, Auto Layout 지정
- Collection View를 화면 상하좌우에 꽉차게, 0으로 지정해줍니다.
1-3, Collection View Cell 크기 지정
- Estimate Size를 Automatic으로 두면, 연산이 중복되어 모양이 이상해집니다. 따라서 None으로 지정해줍니다.
- Cell Size는 본인이 원하는대로 지정해주시면 됩니다.
1-4, Image View와 Label 추가
- 2개의 객체에 Layout을 잡아주면 좋겠죠?
2-1, View Controller와 Collection View의 연결
- Collection VIew를 선택한 상태로 드래그해, View Controller에 가져다 놓습니다.
- delegate : segue와 같이 표현보다, 행동에 대한 내용을 표현
- dataSource: Cell과 데이터를 표현하는 내용에 대해 표현
- 현재는 씬 이동이 없기때문에, dataSource만 해줘도 되지만, 전 둘 다 했습니다 :)
2-2, Collection View Cell identifier 작성
- Collection View Cell을 다루기 위해, identifier 값을 줍니다.
- 해당 Cell이 맞는지 확인을 위한 식별자이므로, 이름을 정확하게 기억할 수 있도록 설정합니다.
2-3, Class 생성
- Custom Cell을 다룰것이기 때문에, Class를 새롭게 정의하고 연결해줍니다.
- 그리고, Class를 따로 생성하지않고, IBOutlet을 생성한다면 경고메세지가 나타나게됩니다.
- 저는 이때, 클래스 생성 과정에서 오타가 발생하여, nameClass를 nameClas로 입력해서 오류찾는데 많은 시간을 소모했습니다..
2-4, Collect Cell의 Class 지정
- 이어서 Outlet이 연결된 클래스를 Collect Cell의 클래스로 잡아줍니다.
3-1, 코드작성
- UICollectionViewDataSource를 프로토콜로 채택해줍니다.
- 프로토콜을 입력하면, 에러메세지에서 Fix를 눌러 자동으로 메서드를 입력해주면 됩니다.
3-2, Cell에 관한 Delegate 작성
- 아이템(항목)의 개수 : collectionView(_:numberOfItemsInsectionsection:)
- 셀 생성 : collectionView(_:cellForItemAt:)
3-3, Item 생성
- 아이템 즉, 표현하고자 할 데이터를 배열로 생성해줍니다.
3-4, 메서드 작성
- 메서드에 맞게 코드를 작성합니다.
- 저는 이때, 빨간색으로 표시한 부분의 오타를 발견해서 수정했네요..
***
- 코드 작성이 끝나면 실행해주시면 됩니다.
Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<UICollectionVIewCell0x4fccb1d0eab0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key myImageView.'
- 저는 이런 에러가 발생해서 꽤나 해멨는데,
- 알고보니 다음과같이 클래스명에 오타를 발견하고 소스코드에서는 수정을 했지만,
- Collect Cell의 클래스 연결하는 곳에서는 수정을 안해줘서 에러가 났었습니다.
***
실행화면
- 이후 에러를 잡고, 실행해보면 상당히 괜찮게 나오지만, able View와 비슷한 구조를 나타냅니다.
- Collection View로 만든 티를 내기 위해, Layout을 조정하는 객체를 이용해 행과 열을 표현할 것입니다.
4, UICollectionViewDelegateFlowLayout 프로토콜 추가
- itemSpacing : 2개의 Cell을 넣기 위해, Cell과 Cell 사이의 거리를 지정합니다.
- width : Collection View 전체 크기에서 itemSpacing을 빼서 Cell 1개의 크기를 계산합니다.
- height : width에 대해서 ImageView 비율로 layout을 진행하고, 비율을 곱한뒤 textAreaHeight를 더해 Cell 전체 높이를 계산합니다.
실행 화면
- 최종화면입니다.
- 기기마다 동일한 규격을 맞추기 위해 레이아웃을 설정해주면 더 완벽했겠지만,
- 간단하게 Collection View를 만들어본것치고는 꽤나 괜찮게 나온것 같습니다.
****
전체 코드
- 코드를 깔끔하게 하기위해, 프로토콜을 채택하여 메서드를 사용하는 부분은 extension으로 정리했습니다.
import UIKit
class ViewController: UIViewController {
let nameList = ["Alisson Becker", "Virgil van Dijk", "TAA", "Robertson", "Thiago Alcantara", "Henderson", "Sadio Mane", "Salah"]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
// UICollectionViewDelegate, UICollectionViewDataSource 프로토콜
extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource{
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return nameList.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectCell", for: indexPath)
as? nameClass else {
return UICollectionViewCell()
}
let img = UIImage(named: "\(nameList[indexPath.row]).png")
cell.myImageView?.image = img
cell.myLabel?.text = nameList[indexPath.row]
return cell
}
}
// UICollectionViewDelegateFlowLayout 프로토콜
extension ViewController: UICollectionViewDelegateFlowLayout{
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let itemSpacing: CGFloat = 10 // 가로에서 Cell과 Cell 사이의 거리
let textAreaHeight: CGFloat = 10 // textLabel이 차지하는 높이
let width: CGFloat = (collectionView.bounds.width - itemSpacing)/2 // Cell 하나의 너비
let height: CGFloat = width * 10/9 + textAreaHeight // Cell 하나의 높이
return CGSize(width: width, height: height)
}
}
class nameClass: UICollectionViewCell{
@IBOutlet weak var myImageView: UIImageView!
@IBOutlet weak var myLabel: UILabel!
}
***
내용 출처
https://greatpapa.tistory.com/54
https://ios-development.tistory.com/103
'iOS > App' 카테고리의 다른 글
박스오피스 앱 만들기(2) (0) | 2022.05.06 |
---|---|
박스오피스 앱 만들기(1) (0) | 2022.05.05 |
Realm이란? (이론) (0) | 2022.04.02 |
APNs (0) | 2022.03.31 |
XML, JSON, YAML (0) | 2022.03.26 |
댓글