LoginSignup
39
24

More than 5 years have passed since last update.

コードのみでcollectionViewの作成

Last updated at Posted at 2017-11-04

storyboardを使わずにコードのみで記述されている情報少ないなーと思い、
これからコードのみで書いていきたいという人(少数だとは思いますが)がいた時のための保存です。

コードのみでアプリを作ろうと思った理由

・AutoLayoutなんか難しそう
・複数人開発でstoryboard一緒にいじっちゃうと怖い
・storyboard内での設定を見落としてしまいがち

storyboard使い慣れてなくて、ただ単に「逃げ」です。
storyboardを使用する利点もかなりあると思っています。

collectionViewを生成

まずは、ViewControllerにcollectionViewを生成していきます。
(ここでは、簡易的にViewController内にcollectionViewなどを配置しますが、普段の開発ではViewController内にUIパーツを配置はあまりしていません。)
Cellはとりあえず生成。

ViewController.swift

//スクリーンサイズの取得
let screenSize: CGSize = CGSize(width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height)

final class ViewController: UIViewController {

    private let collectionView: UICollectionView = {
        //セルのレイアウト設計
        let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()

        //各々の設計に合わせて調整
        layout.scrollDirection = .vertical
        layout.minimumInteritemSpacing = 0
        layout.minimumLineSpacing = 0

        let collectionView = UICollectionView( frame: CGRect(x: 0, y: 0, width: screenSize.width, height: screenSize.height ), collectionViewLayout: layout)
        collectionView.backgroundColor = UIColor.white
        //セルの登録
        collectionView.register(CollectionViewCell.self, forCellWithReuseIdentifier: "CollectionViewCell")
        return collectionView
    }()
}

CollectionViewCell.swift

final class CollectionViewCell: UICollectionViewCell {

    override init(frame: CGRect) {
        super.init(frame: frame)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}

DataSource,Delegateの設定

DataSource,Delegateについて設定することで、cellの数、cellに与える情報などを指定していきます。
ただ単に表示してあげたいのであればこれで終わり。
結構簡単ですね!!

ViewController.swift

final class ViewController: UIViewController {

    fileprivate let fruits: [String] = ["apple", "grape", "lemon", "banana", "cherry", "strobery", "peach", "orange"]

    override func viewDidLoad() {
        super.viewDidLoad()

        //生成したcollectionViewのdataSourceとdelegteを紐づける
        collectionView.dataSource = self
        collectionView.delegate = self

        view.addSubview(collectionView)
  }
}


//cellに与える情報の設定
extension ViewController: UICollectionViewDataSource {

    //cellの個数設定
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return fruits.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell", for: indexPath) as! CollectionViewCell

        let cellText = fruits[indexPath.item]
        cell.setupContents(textName: cellText)

        return cell
    }
}

//イベントの設定(何もなければ記述の必要なし)
extension ViewController: UICollectionViewDelegate {

}

//cellのサイズの設定
extension ViewController: UICollectionViewDelegateFlowLayout {

  func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

      //ここでは画面の横サイズの半分の大きさのcellサイズを指定
      return CGSize(width: screenSize.width / 2.0, height: screenSize.width / 2.0)
  }
}

cellには配列に持たせたStringを表示させるLabelを配置。

CollectionViewCell.swift
final class CollectionViewCell: UICollectionViewCell {

    private let fruitsNameLabel: UILabel = {
        let label = UILabel()
        label.frame = CGRect(x: 0, y: 0, width: screenSize.width / 2.0, height: screenSize.width / 2.0)
        label.textColor = UIColor.gray
        label.textAlignment = .center
        return label
    }()

    override init(frame: CGRect) {
        super.init(frame: frame)
        setup()
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }


    private func setup() {
        layer.borderColor = UIColor.darkGray.cgColor
        layer.borderWidth = 3.0

        contentView.addSubview(fruitsNameLabel)
    }

    func setupContents(textName: String) {
        fruitsNameLabel.text = textName
    }
}

これだけの記述でこのようなViewが簡単に作成できます。
スクリーンショット 2017-11-04 18.48.43.png

viewControllerの移動(データの受け渡し)

タップされたcellのStringのデータをNextViewControllerに引き渡したし、NextViewControllerをpresentしたいとおもいます。
NextViewControllerもstoryboardは使いません。

NextViewCotroller.swift

final class NextViewController: UIViewController {

    private let nameLabel: UILabel = {
        let label = UILabel()
        label.frame = CGRect(x: 0, y: 0, width: screenSize.width, height: 100)
        label.layer.position = CGPoint(x: screenSize.width / 2.0, y: screenSize.height / 2.0)
        label.textAlignment = .center
        return label
    }()

    //初期値にStringを受け取る
    init(name: String) {
        //受け取ったデータをnameLabelのテキストにする
        nameLabel.text = name
        super.init(nibName: nil, bundle: nil)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = UIColor.white
        view.addSubview(nameLabel)
    }

}

viewController内でのNextViewControllerへの移動の記述

ViewController.swift

final class ViewController: UIViewController {

    //selectされたindexPathを受け取り、NextViewControllerに伝える
    fileprivate func moveNextVC(indexPath: IndexPath) {
        let itemName = fruits[indexPath.item]
        let nextVC = NextViewController(name: itemName)
        present(nextVC, animated: true, completion: nil)
    }
}

extension ViewController: UICollectionViewDelegate {

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        moveNextVC(indexPath: indexPath)
    }
}

おわりに

巷の技術書などではstoryboardを使って説明しているが、コードのみでも簡単にUIパーツを配置したり、ViewController間の移動も行うことができる。
storyboard使わないと、safeAreaとか、パーツの幅や高さの計算とか色々ありますが、結構楽にかけたりするものです。
AutoLayoutに悩ませている方々、コードのみもかなり楽です。

39
24
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
39
24