【Swift】UICollectionViewDelegateの使い方。コレクションビューのセルが選択されたときにイベントを発生させる。(Swift 2.1、XCode 7.2)
UICollectionViewDelegateとは
前回までの記事でUICollectionView(以下、コレクションビュー)を使ってセルを格子状に並べて表示する方法や並べ方をカスタマイズする方法について説明した。⇒「記事」
本記事では、UICollectionViewDelegate(以下、コレクションビューデリテート)を使ってコレクションビューのセルをタップしたときにイベントを発生させる方法について説明する。
コレクションビューデリゲートとは、コレクションビューの中のセルが選択または編集されたときに呼び出されるメソッドが定義されたプロトコルである。
考え方はUITableViewDelegateと同じで、メソッドはすべてOptionalなので必要なものだけ実装すればいい。⇒「UITableViewDelegateの記事」
データを選択時のイベントを実装する
では、イベント処理を実装してみよう。以降の手順は前回記事の続きから行うので、実装を試してみる人は前回記事を読んでから行うことをお勧めする。⇒「前回記事」
Ctrlキーを押しながらコレクションビューをデバイス画面の上にある黄色い丸に運び、ポップアップで表示されたメニューから「delegate」を選択する。これは、コレクションビューのイベントが発生したときは、UIViewControllerのデリゲートメソッドを呼び出すという設定である。
UIViewController.swiftを開き、以下のコードのように変更する。
変更箇所は青色網掛けの箇所で、UICollectionViewDelegateプロトコルを適用し、セル選択時に呼び出されるメソッドを実装した。
セル選択時に呼び出されるメソッドの中で、選択されたセルのインスタンスを取得してラベルの値を変更するようにした。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
// // ViewController.swift // import UIKit class ViewController: UIViewController, UICollectionViewDataSource,UICollectionViewDelegate { let member = ["青山","阿部","加藤","川島"] //データの個数を返すメソッド func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return 30 } //データを返すメソッド func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { //コレクションビューから識別子「TestCell」のセルを取得する。 let cell = collectionView.dequeueReusableCellWithReuseIdentifier("TestCell", forIndexPath: indexPath) as! TestCollectionViewCell //セルの背景色をランダムに設定する。 cell.backgroundColor = UIColor(red: CGFloat(drand48()), green: CGFloat(drand48()), blue: CGFloat(drand48()), alpha: 1.0) //セルのラベルに番号を設定する。 cell.testLabel.text = String(indexPath.row + 1) return cell } //セル選択時に呼び出されるメソッド func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) { let testCell = collectionView.cellForItemAtIndexPath(indexPath) as! TestCollectionViewCell let resultIndex = indexPath.row % 4 //セルの中のラベルの値を変更する。 testCell.testLabel.text = member[resultIndex] } //最初からあるメソッド override func viewDidLoad() { super.viewDidLoad() } } |
TestCollectionViewLayout.swiftは、セルのレイアウトをジグザグではなく並べて表示するためにy座標を更新する位置を移動した。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
// // TestCollectionViewLayout.swift // import UIKit class TestCollectionViewLayout: UICollectionViewLayout { let numberColumns = 2 //列数 let height:CGFloat = 50 //セルの高さ //レイアウト private var layoutData = [UICollectionViewLayoutAttributes]() //レイアウトを準備するメソッド override func prepareLayout() { //全体の幅 let allWidth = CGRectGetWidth(collectionView!.bounds) - collectionView!.contentInset.left - collectionView!.contentInset.right //列の幅 let columnWidth = allWidth / CGFloat(numberColumns) //座標 var y:CGFloat = 0 var x:CGFloat = 0 //要素数ぶんループ for count in 0 ..< collectionView!.numberOfItemsInSection(0) { let indexPath = NSIndexPath(forItem:count, inSection:0) //レイアウトの配列に位置とサイズを登録する。 let frame = CGRect(x:x, y:y, width:columnWidth, height: height) let attributes = UICollectionViewLayoutAttributes(forCellWithIndexPath: indexPath) attributes.frame = frame layoutData.append(attributes) //X座標を更新 if(count % 2 == 0) { x = columnWidth } else { x = 0 //Y座標を更新 y = y + height } } } //レイアウトを返すメソッド override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? { return layoutData } //全体サイズを返すメソッド override func collectionViewContentSize() -> CGSize { //全体の幅 let allWidth = CGRectGetWidth(collectionView!.bounds) - collectionView!.contentInset.left - collectionView!.contentInset.right //全体の高さ let allHeight = CGFloat(collectionView!.numberOfItemsInSection(0)) * height return CGSize(width:allWidth, height:allHeight) } } |
以下は実際のプレイ動画。何となく神経衰弱。