今回はCollectionViewを使って横スクロールできるカード型デザインを実装しました!
##1. Storyboardの編集
まずはStoryboardでViewController上にCollectionViewを配置します。画面いっぱいにパーツを広げ、Constrainsを適切に設定しておきます。
デフォルトでCollectionViewのスクロール方向はVerticalになっているのでScroll Direction
をHorizontal
に変更しておきましょう。
##2. CollectionViewのカスタムセルを作成
次にカスタムセルのxibファイルを作成します。
XCodeメニューのFile > New > File...とたどり、Cocoa Touch Classを選択します。
クラスの型はUICollectionViewCellにして、名前をつけます(ここではCollectionViewCellという名前をつけています)。この際にAlso create XIB file
にチェックをつけるのを忘れないように注意してください。
CollectionViewCell.xibファイルができたらパーツを適宜配置します。今回は背景のUIImageViewを画面いっぱいに広げ、その上にUILabelを2つ配置しました。
UIImageViewのContentModeは以下のように'AspectFillとし、
Clip to Bounds`にチェックを入れるのを忘れないように注意してください。
cellにはidentifierをつけておきます。ここではcell
としておきます。
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番目のメソッドでセルを再利用しているところがポイントです。
-
セルの中身
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {}
-
セル同士の間隔
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {}
-
セルのサイズ
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {}
-
余白の調整
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
}
}