■はじめに
ヘッダーとアイコン画像、タイトルを表示するUICollectionViewをコードで実装し、サンプルを作ってみました。
※2019/05 追記:xibファイルを使った実装については以下の記事で取り上げています。
https://www.hfoasi8fje3.work/entry/2019/05/02/235410
■開発環境
・Xcode 10.1
・Swift 4.2.1
■サンプルのイメージ
※アイコン画像は以下サイトのものを使用させていただきました。
■実装部分
・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(CollectionViewCell.self, forCellWithReuseIdentifier: "Cell") 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 3 } // セルの設定 func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell",for: indexPath as 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: 100, height: 100) } // セルの余白 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 } }
・CollectionViewCell.swift
import UIKit // CollectionViewのセル設定 class CollectionViewCell: UICollectionViewCell { private let cellNameLabel: UILabel = { let label = UILabel() label.frame = CGRect(x: 15, y: 50, width: 50, height: 50) label.font = .systemFont(ofSize: 14, weight: UIFont.Weight(rawValue: 1)) label.textColor = UIColor.darkGray label.textAlignment = .center return label }() private let cellImageView: UIImageView = { let imageView = UIImageView() imageView.frame = CGRect(x: 15, y: 10, width: 50, height: 50) return imageView }() override init(frame: CGRect) { super.init(frame: frame) setup() } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } private func setup() { contentView.addSubview(cellImageView) contentView.addSubview(cellNameLabel) } func setUpContents(image: UIImage, textName: String) { cellImageView.image = image cellNameLabel.text = textName } }
■おわりに
アイコン画像とタイトルの配置など、もっとうまく実装できる部分があると思うのですが、ブログにアウトプットする前にお蔵入りしてしまいそうなので一旦記事にしました!UICollectionViewをコードのみで実装する記事は少なく感じたので、少しでも参考になれば幸いです。
■関連リンク
・UICollectionView - UIKit | Apple Developer Documentation