見出し画像

【徒然iOS】気ままにUIKit37〜ザ・神経衰弱!!!!UICollectionViewDelegate〜

概要

このマガジンは四十を過ぎたおっさんが、

を参考にStoryboardでiOSアプリを完全に趣味で楽しんでいるだけな記事を気ままに上げてます。

今回

をやる〜〜〜!

前準備

  1. 念の為、バックアップ

  2. 新しいクラス

  3. ビューコントローラの追加

  4. イニシャルビューの変更

をいつも通りやってから本題へ💃

こんな感じかな💦

本題

コレクションビューデリゲートとは、

コレクションビューの中のセルが選択または編集されたときに呼び出されるメソッドが定義されたプロトコル

デリゲート

については、

でもやったとおりなんだけど、要は

ビューのイベント処理

てことで、、、💦

⒈記事に書いてるとおり、前回までのビューを新規で仕込む

でやった操作を参考に!

はい!準備完了🕺

⒉コレクションビューをdelegateする。

これは、コレクションビューのイベントが発生したときは、UIViewControllerのデリゲートメソッドを呼び出すという設定だそうだ👀

て感じでCollectionView全体をdelegateさせて
コネクションインスペクターで確認してdelegete出来てるね、ドキドキ💦

⒊コードを組み込む

今回組み込むコード

//  ViewController.swift
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
//
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)
    }
}

てことで、書き換え〜〜〜〜
ViewController側から直してみると、、、

てな感じで恒例のprivateを先頭に付けるかえ?
と聞いてくるので、、、

これは既にメソッドの書き方が変わってると判断して、
JumptoDefinitionでdidSelectItemを検索してみると

//セル選択時に呼び出されるメソッド
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
//セル選択時に呼び出されるメソッド(JumptoDefinition)
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)

と既に書き方が変わっていることがわかるので、変更

警告が全部消えた🕺

同様に、Layoutクラスも直して

てな感じで赤警告なんかがないことを確認

⒋シミュレータを実行

てな感じで神経衰弱完成🕺

でけた
以上。

⒌ブラッシュアップ

今回も、シミュレータで実行に行き着くまでに、AutoLayoutなんかは実施しないとラベル文字も表示できないため、既に実施済みなので割愛💦

今回のコード

class CollectionViewDelegateController: UIViewController, UICollectionViewDataSource,UICollectionViewDelegate {
    
    let member = ["青山","阿部","加藤","川島"]
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 30
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        
        //コレクションビューから識別子「TestCell」のセルを取得する。
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyCollectionDelegateCell", for: indexPath) as! MyCollectionDelegateCell
        
        //セルの背景色をランダムに設定する。
        cell.backgroundColor = UIColor(
            red: CGFloat(drand48()),
            green: CGFloat(drand48()),
            blue: CGFloat(drand48()),
            alpha: 1.0
        )
        //セルのラベルに番号を設定する。
        cell.myDelegateLabel.text = String(indexPath.row + 1)
        return cell
    }
    //セル選択時に呼び出されるメソッド
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        let myCell = collectionView.cellForItem(at: indexPath as IndexPath) as! MyCollectionDelegateCell
        let resultIndex = indexPath.row % 4
        //セルの中のラベルの値を変更する。
        myCell.myDelegateLabel.text = member[resultIndex]
    }
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}
import UIKit

class MyCollectionDelegateLayout: UICollectionViewLayout {
    let numberColumns = 2 //列数
    let height:CGFloat = 50 //セルの高さ
    //レイアウト
    private var layoutData = [UICollectionViewLayoutAttributes]()
    //レイアウトを準備するメソッド
    override func prepare() {
        //全体の幅
        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!.numberOfItems(inSection: 0) {
            let indexPath = NSIndexPath(item:count, section:0)
            //レイアウトの配列に位置とサイズを登録する。
            let frame = CGRect(x:x, y:y, width:columnWidth, height: height)
            let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath as IndexPath)
            attributes.frame = frame
            layoutData.append(attributes)
            //X座標を更新
            if(count % 2 == 0) {
                x = columnWidth
            } else {
                x = 0
                //Y座標を更新
                y = y + height
            }
        }
    }
    //レイアウトを返すメソッド
    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        return layoutData
    }
    //全体サイズを返すメソッド
    override var collectionViewContentSize: CGSize {
        //全体の幅
        let allWidth = CGRectGetWidth(collectionView!.bounds) - collectionView!.contentInset.left - collectionView!.contentInset.right
        //全体の高さ
        let allHeight = CGFloat(collectionView!.numberOfItems(inSection: 0)) * height
        return CGSize(width:allWidth, height:allHeight)
    }
}

Apple公式

まとめ

これでCollectionView関連が完了だねえ🕺

見ていてわかったと思うけど、

TableViewと結構、やり方とか気をつけるポイントが重複して似通っている

ことが多いなあと。特に

セクション数を返すメソッドの変更とかそっくりだからね

前回までに書いたポイントとか教訓に気をつけてもらいながら、色々、自分なりに作り変えるといいかもね〜〜〜〜!

なんかも参考に🕺

さて次回は、

をやる〜〜〜!

さてと、完全に余談だけど、

今週までに動かしたかった機能の記事は全て書けたし、

でも書いたとおり、新しいカセットテープが届いたので、

週末はゆっくり読書とかPCから離れて、

このカセットを垂れ流しながらゆっくりやりたいことする🕺

毎月恒例の大濠公園ゴミ拾いボランティアとかやってアナログ生活 藁🤣

エンジニア経験も長いからわかるけど、
週末とか休日まで丸一日、PCとかデジタル漬け生活送っても、脳疲労が取れないから却って効率悪いしぃぃぃ

とにかく、

💃みなさん良い週末を🕺

と言いつつ、気が向いたら、週末に

先週まで遊んでた

を、12月頭まで作ってた

にまとめて遊ぶ作業でもすっかな〜〜〜
って疲れるし、この連載が終わってからやっても全然納期なんてないから、
多分やらない可能性が高いけど藁藁🤣

所詮、気ままな趣味なんで

この記事が気に入ったらサポートをしてみませんか?