Help us understand the problem. What is going on with this article?

【Swift】CollectionViewでカード型デザインを実装しよう

More than 1 year has passed since last update.

今回はCollectionViewを使って横スクロールできるカード型デザインを実装しました!

完成品

cardDesignSample.gif

1. Storyboardの編集

まずはStoryboardでViewController上にCollectionViewを配置します。画面いっぱいにパーツを広げ、Constrainsを適切に設定しておきます。
スクリーンショット 2019-06-11 11.05.08.png

デフォルトでCollectionViewのスクロール方向はVerticalになっているのでScroll DirectionHorizontalに変更しておきましょう。
スクリーンショット 2019-06-11 11.55.23.png

2. CollectionViewのカスタムセルを作成

次にカスタムセルのxibファイルを作成します。
XCodeメニューのFile > New > File...とたどり、Cocoa Touch Classを選択します。
スクリーンショット 2019-06-11 11.12.45.png

クラスの型はUICollectionViewCellにして、名前をつけます(ここではCollectionViewCellという名前をつけています)。この際にAlso create XIB fileにチェックをつけるのを忘れないように注意してください。

スクリーンショット 2019-06-11 11.13.00.png

CollectionViewCell.xibファイルができたらパーツを適宜配置します。今回は背景のUIImageViewを画面いっぱいに広げ、その上にUILabelを2つ配置しました。
スクリーンショット 2019-06-11 11.17.24.png

UIImageViewのContentModeは以下のように'AspectFillとし、Clip to Bounds`にチェックを入れるのを忘れないように注意してください。
スクリーンショット 2019-06-11 11.50.43.png

cellにはidentifierをつけておきます。ここではcellとしておきます。
スクリーンショット 2019-06-11 11.22.26.png

CollectionView.swiftでは配置したパーツの宣言を行い、背景の角を丸くしておきます。関連付けも忘れないようにしておきましょう。

import UIKit

class CollectionViewCell: UICollectionViewCell {

    @IBOutlet var titleLabel: UILabel!
    @IBOutlet var dateLabel: UILabel!
    @IBOutlet var backgroundImageView: UIImageView!

    override func awakeFromNib() {
        super.awakeFromNib()

        backgroundImageView.layer.cornerRadius = 12    
    }
}

3. ViewControllerの編集

初めにViewDidLoad()内でregister(_:forCellWithReuseIdentifier:)メソッドを使ってCollectionViewCellの登録を行います。第一引数にUINibオブジェクトを渡し、第二引数では先ほどcellにつけたcellというidentifierを渡しています。UINibのnibNameはCollectionViewのxibファイル名と一致していることを確認してください。

import UIKit

class ViewController: UIViewController {

    @IBOutlet var horizontalCollectionView: UICollectionView!

    override func viewDidLoad() {
        super.viewDidLoad()

        let nib = UINib(nibName: "CollectionViewCell", bundle: .main)
        horizontalCollectionView.register(nib, forCellWithReuseIdentifier: "cell")
    }  
}

次にViewControllerにUICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayoutプロトコルを実装します。今回は以下の4つのメソッドを実装しました。

コレクションビューに配置するセルの個数
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {}1番目のメソッドではphotoArrayの中に入っている写真の個数だけセルを返し、3番目のメソッドでセルを再利用しているところがポイントです。

  1. セルの中身
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {}

  2. セル同士の間隔
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {}

  3. セルのサイズ
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {}

  4. 余白の調整
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {}

全体のコードは以下の通りです。
ViewController.swift

import UIKit

class ViewController: UIViewController {

    @IBOutlet var horizontalCollectionView: UICollectionView!

    var viewWidth: CGFloat!
    var viewHeight: CGFloat!
    var cellWidth: CGFloat!
    var cellHeight: CGFloat!
    var cellOffset: CGFloat!
    var navHeight: CGFloat!

    var photoArray = ["ny","italy","australia","france"]
    var titleArray = ["ニューヨーク","イタリア","オーストラリア","フランス"]

    override func viewDidLoad() {
        super.viewDidLoad()

        viewWidth = view.frame.width
        viewHeight = view.frame.height
        navHeight = self.navigationController?.navigationBar.frame.size.height

        horizontalCollectionView.delegate = self
        horizontalCollectionView.dataSource = self

        let nib = UINib(nibName: "CollectionViewCell", bundle: .main)
        horizontalCollectionView.register(nib, forCellWithReuseIdentifier: "cell")

        self.navigationController!.navigationBar.setBackgroundImage(UIImage(), for: .default)
        self.navigationController!.navigationBar.shadowImage = UIImage()
        self.navigationController?.navigationBar.tintColor = .white
        self.navigationController?.navigationBar.titleTextAttributes = [
            .foregroundColor: UIColor.white
        ]

    }

}

extension ViewController: UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return photoArray.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell
        cell.backgroundColor = UIColor.white
        cell.layer.cornerRadius = 12
        cell.layer.shadowOpacity = 0.4
        cell.layer.shadowRadius = 12
        cell.layer.shadowColor = UIColor.black.cgColor
        cell.layer.shadowOffset = CGSize(width: 8, height: 8)
        cell.layer.masksToBounds = false
        cell.titleLabel.text = "\(titleArray[indexPath.row])への旅"
        cell.dateLabel.text = "06/08~06/15"
        cell.backgroundImageView.image = UIImage(named: photoArray[indexPath.row])
        return cell

    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
        return 24
    }
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        cellWidth = viewWidth-75
        cellHeight = viewHeight-300
        cellOffset = viewWidth-cellWidth
        return CGSize(width: cellWidth, height: cellHeight)
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        return UIEdgeInsets(top: -navHeight,left: cellOffset/2,bottom: 0,right: cellOffset/2)
    }

}

CollectionView.swift

import UIKit

class CollectionViewCell: UICollectionViewCell {

    @IBOutlet var titleLabel: UILabel!
    @IBOutlet var dateLabel: UILabel!
    @IBOutlet var backgroundImageView: UIImageView!

    override func awakeFromNib() {
        super.awakeFromNib()

        backgroundImageView.layer.cornerRadius = 12    
    }
}
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away