Swift 5: Custom CollectionView Cells (Programmatically) Xcode 11 - 2020 iOS
override func layoutSubviews() {
super.layoutSubviews()
let height = contentView.frame.size.height
let width = contentView.frame.size.width
label.frame = CGRect(x: 5, y: height - 50, width: width - 10, height: 50)
imageView.frame = CGRect(x: 5, y: 0, width: width - 10, height: height - 50)
}
layoutSubviews()
함수를 오버라이드할 때 적용import UIKit
class CollectionViewController: UIViewController {
private let collectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .vertical
layout.minimumLineSpacing = 1
layout.minimumInteritemSpacing = 1
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionView.alwaysBounceVertical = true
collectionView.register(CustomCollectionViewCell.self, forCellWithReuseIdentifier: CustomCollectionViewCell.identifier)
return collectionView
}()
override func viewDidLoad() {
super.viewDidLoad()
setUI()
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
collectionView.frame = view.bounds
}
private func setUI() {
view.backgroundColor = .systemBackground
view.addSubview(collectionView)
collectionView.delegate = self
collectionView.dataSource = self
}
}
extension CollectionViewController: UICollectionViewDelegate {
}
extension CollectionViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CustomCollectionViewCell.identifier, for: indexPath) as? CustomCollectionViewCell else {
return UICollectionViewCell()
}
if let number = (1...10).randomElement() {
let text = "random animal #\(number)"
let imageName = "animal_\(number)"
let model = ImageModel(text: text, imageName: imageName)
cell.configure(with: model)
}
return cell
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 100
}
}
extension CollectionViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = view.frame.size.width / 3
return CGSize(width: width - 4, height: width - 4)
}
}
configure
함수 적용 시 커스텀 셀 사용을 위한 guard let
바인딩 적용import UIKit
class CustomCollectionViewCell: UICollectionViewCell {
static let identifier = "CustomCollectionViewCell"
private let imageView: UIImageView = {
let imageView = UIImageView()
imageView.clipsToBounds = true
return imageView
}()
private let label: UILabel = {
let label = UILabel()
label.textColor = .label
label.font = .systemFont(ofSize: 12, weight: .bold)
label.numberOfLines = 0
label.textAlignment = .center
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
setUI()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
let height = contentView.frame.size.height
let width = contentView.frame.size.width
label.frame = CGRect(x: 5, y: height - 50, width: width - 10, height: 50)
imageView.frame = CGRect(x: 5, y: 0, width: width - 10, height: height - 50)
}
override func prepareForReuse() {
super.prepareForReuse()
imageView.image = nil
label.text = nil
}
private func setUI() {
contentView.backgroundColor = .systemPink
contentView.addSubview(label)
contentView.addSubview(imageView)
}
func configure(with model: ImageModel) {
label.text = model.text
imageView.image = UIImage(named: model.imageName)
}
}
prepareForeReuse()
함수 오버라이드 시 셀의 공통적으로 사용되는 부분을 제외한 나머지는 nil
로 줄 수 있음import Foundation
struct ImageModel {
let text: String
let imageName: String
}