以前、UICollectionViewをコードのみで実装する方法を以下の記事で取り上げました。
https://www.hfoasi8fje3.work/entry/2019/02/14/000000
今回は、上記の記事の実装をもとに、カスタムセルをxibで作成し適用する方法を試してみます。
■開発環境
・Xcode 10.2
・Swift 5.0
■xibでカスタムセルを作成
File→New→File...を選択し、Cocoa Touch Classを選択
Also create XIB fileにチェックを入れてファイル作成
→CollectionViewCell.xibとCollectionViewCell.swiftが作成されます
・CollectionViewCell.xib
UIImageViewとUILabelを配置します。
※UIImageViewの設定
※UILabelの設定
・CollectionViewCell.swift
以下のように実装します。
import UIKit class CollectionViewCell: UICollectionViewCell { @IBOutlet weak var imageView: UIImageView! @IBOutlet weak var label: UILabel! override func awakeFromNib() { super.awakeFromNib() } func setUpContents(image: UIImage, textName: String) { imageView.image = image label.text = textName } }
■その他実装部分
・ViewController.swift
import UIKit class ViewController: UIViewController { let sectionName = [["Section1"], ["Section2"], ["Section3"]] let data = [["item1", "item2", "item3"], ["item4", "item5", "item6"], ["item7", "item8", "item9"]] let photo = [["photo1", "photo2", "photo3"], ["photo4", "photo5", "photo6"], ["photo7", "photo8", "photo9"]] override func viewDidLoad() { super.viewDidLoad() // UICollectionViewを生成 let collectionView = UICollectionView(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.height), collectionViewLayout: UICollectionViewFlowLayout()) collectionView.backgroundColor = UIColor.white collectionView.register(UINib(nibName: "CollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "CollectionViewCell") collectionView.register(CollectionViewHeader.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "Header") collectionView.delegate = self collectionView.dataSource = self self.view.addSubview(collectionView) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } } extension ViewController: UICollectionViewDelegate { // セル選択時の処理 func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { print(data[indexPath.section][indexPath.row]) } } extension ViewController: UICollectionViewDataSource { // セルの数を返す func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return self.data[section].count } // ヘッダーの数 func numberOfSections(in collectionView: UICollectionView) -> Int { return self.sectionName.count } // セルの設定 func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell", for: indexPath) as! CollectionViewCell let cellImage = UIImage(named: photo[indexPath.section][indexPath.item])! let cellText = data[indexPath.section][indexPath.item] cell.setUpContents(image: cellImage,textName: cellText) return cell } // ヘッダーの設定 func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { let collectionViewHeader = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "Header", for: indexPath) as! CollectionViewHeader let headerText = sectionName[indexPath.section][indexPath.item] collectionViewHeader.setUpContents(titleText: headerText) return collectionViewHeader } } extension ViewController: UICollectionViewDelegateFlowLayout { // セルの大きさ func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { return CGSize(width: 80, height: 80) } // セルの余白 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets { return UIEdgeInsets(top: 20, left: 20, bottom: 20, right: 20) } // ヘッダーのサイズ func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize { return CGSize(width: self.view.frame.size.width, height: 50) } }
・CollectionViewHeader.swift
import UIKit // CollectionViewのヘッダー設定 class CollectionViewHeader: UICollectionReusableView { override init(frame: CGRect) { super.init(frame: frame) setUpViews() } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } var titleLabel: UILabel = { let label = UILabel() label.font = .systemFont(ofSize: 16, weight: UIFont.Weight(rawValue: 10)) label.textColor = UIColor.darkGray label.translatesAutoresizingMaskIntoConstraints = false return label }() func setUpViews() { backgroundColor = UIColor(red: 245/255, green: 245/255, blue: 245/255, alpha: 1.0) addSubview(titleLabel) titleLabel.topAnchor.constraint(equalTo: self.topAnchor, constant: 0).isActive = true titleLabel.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 20).isActive = true titleLabel.widthAnchor.constraint(equalTo: self.widthAnchor, multiplier: 1).isActive = true titleLabel.heightAnchor.constraint(equalTo: self.heightAnchor, multiplier: 1).isActive = true } func setUpContents(titleText: String) { titleLabel.text = titleText } }
■完成したサンプル画面
■関連リンク
・https://developer.apple.com/documentation/uikit/uicollectionview