횡스크롤이 가능한 UICollectionView를 스토리 보드 없이 만들어봅니다.
스토리 보드 없이 SnapKit, Than 라이브러리를 사용해서 뷰를 그릴 예정입니다.
MainView.swift
뷰에 관한 파일을 먼저 정의합니다.
class MainView: UIView {
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()).then {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
$0.backgroundColor = .white
$0.contentInset = UIEdgeInsets.init(top: 0, left: 20, bottom: 0, right: 0)
$0.showsHorizontalScrollIndicator = false
$0.collectionViewLayout = layout
}
override init(frame: CGRect) {
super.init(frame: frame)
setup()
bindConstraints()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setup()
bindConstraints()
}
func setup() {
backgroundColor = .white
addSubview(collectionView)
}
func bindConstraints() {
collectionView.snp.makeConstraints { (make) in
make.left.right.equalToSuperview()
make.centerY.equalToSuperview()
make.height.equalTo(200)
}
}
}
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()).then {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
$0.backgroundColor = .white
$0.contentInset = UIEdgeInsets.init(top: 0, left: 20, bottom: 0, right: 0)
$0.showsHorizontalScrollIndicator = false
$0.collectionViewLayout = layout
}
UICollectionView는 초기화할 당시에 collectionViewLayout 인자를 포함해서 초기화 시켜줘야합니다. 컴파일 오류는 나지 않지만 런타임에서 에러가 발생합니다. 따라서 인자로 일단은 넣어놓고 내부에서 다시 정의를 해주는 식으로 진행하였습니다 ㅠㅠ
횡스크롤을 설정하기 위하여 UICollectionViewFlowLayout 를 다시 정의한뒤 속성을 지정해주고 collectionView에 다시 설정해줍니다.
contentInset속성은 콜렉션뷰가 시작하는데 초기 padding값을 설정해주는 속성입니다.
MainCell.swift
import UIKit
class MainCell: UICollectionViewCell {
static let registerId = "\(MainCell.self)"
let main = UIView().then {
$0.backgroundColor = .red
}
override init(frame: CGRect) {
super.init(frame: frame)
setup()
bindConstraints()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setup()
bindConstraints()
}
private func setup() {
backgroundColor = .red
addSubview(main)
}
private func bindConstraints() {
main.snp.makeConstraints { (make) in
make.edges.equalTo(0)
}
}
}
콜렉션뷰 안에 들어갈 셀을 정의해줍니다. 셀에는 색깔이 있는 뷰 하나만 그려서 넣었습니다.
ViewCollection.swift
import UIKit
class ViewController: UIViewController {
private lazy var mainView = MainView.init(frame: self.view.frame)
static func instance() -> ViewController {
return ViewController.init(nibName: nil, bundle: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
view = mainView
setupCollectionView()
}
private func setupCollectionView() {
mainView.collectionView.delegate = self
mainView.collectionView.dataSource = self
mainView.collectionView.register(MainCell.self, forCellWithReuseIdentifier: MainCell.registerId)
}
}
extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 5
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MainCell.registerId, for: indexPath) as? MainCell else {
return UICollectionViewCell()
}
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize.init(width: 100, height: 100)
}
}
private func setupCollectionView() {
mainView.collectionView.delegate = self
mainView.collectionView.dataSource = self
mainView.collectionView.register(MainCell.self, forCellWithReuseIdentifier: MainCell.registerId)
}
콜렉션뷰를 설정하기 위해선 delegate, dataSource를 정의하고 cell을 등록해줘야합니다.
delegate는 터치 이벤트를 정의하기 위해 사용됩니다. 선택을 하지 않는거라면 굳이 필요하진 않습니다.
datasource는 콜렉션 뷰 안에 들어가는 데이터를 정의하기 위해 사용됩니다.
셀을 등록할때에는 register함수를 사용하고 어떤 셀인지, 셀 id와 함께 정의해줍니다.
extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 5
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MainCell.registerId, for: indexPath) as? MainCell else {
return UICollectionViewCell()
}
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize.init(width: 100, height: 100)
}
}
extension으로 UICollectionViewDelegate, UICollectionViewDataSource를 구현해줍니다.
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
하나의 섹션안에 몇개의 아이템이 들어가는지 정의해줍시다. 여기에서는 5개만 보여주기 때문에 5라고 정의해줍니다.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
콜렉션 뷰 안에 들어갈 cell을 정의해주면 됩니다. 이 예제의 경우에는 MainCell을 사용하기 때문에 MainCell을 반환해주면 됩니다.
이 두개의 함수만 정의하면 정상적으로 동작합니다. 예제 아래에 적혀있는 추가적인 함수는 셀 크기를 정의하는 함수입니다.
UICollectionViewDelegateFlowLayout안에 들어있는 함수입니다.
'iOS' 카테고리의 다른 글
📱iOS Stretchy header 오토 레이아웃으로 구현하기 (Snapkit) (0) | 2020.05.31 |
---|---|
📱화면 절반만 차지하는 iOS모달 구현하기 (0) | 2020.05.15 |
[iOS/Swift] 선택된 셀이 표시되는 UICollectionView (0) | 2020.02.08 |
[iOS/Swift] 스토리보드 없이 UIScrollView 만들기 (using Snapkit) (2) | 2020.02.04 |
[iOS13] 스토리보드 없이 프로젝트 시작하기 (0) | 2020.01.26 |