26
28

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2019-06-11

今回は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    
    }
}
26
28
3

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
26
28

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?