1
0

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 1 year has passed since last update.

【Swift】CollectionViewについて

Posted at

CollectionViewとは

CollectionViewとは、複数の要素を一覧表示するためのUIコンポーネントのことです。Swiftでは、UICollectionViewを使ってCollectionViewを作成することができます。

例文

class ViewController: UIViewController, UICollectionViewDataSource {
    @IBOutlet var collectionView: UICollectionView!

    let items = ["Apple", "Banana", "Orange", "Pineapple", "Strawberry"]

    override func viewDidLoad() {
        super.viewDidLoad()

        collectionView.dataSource = self

        let layout = UICollectionViewFlowLayout()
        layout.itemSize = CGSize(width: 100, height: 100)
        collectionView.collectionViewLayout = layout
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return items.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! CollectionViewCell

        cell.titleLabel.text = items[indexPath.row]

        return cell
    }
}

この例では、itemsという配列に要素を設定し、UICollectionViewDataSourceプロトコルを実装することで、UICollectionViewに表示する要素を定義しています。

UICollectionViewDataSourceについて

UICollectionViewに表示するデータを提供することができます。データの取得や変更、セルの作成などを担当します。

UICollectionViewDelegateについて

UICollectionViewの動作をカスタマイズすることができます。セルの選択、スクロール、レイアウトの変更など、様々なアクションに対応できます。

具体的な例文

セルの表示

UICollectionViewDataSourceプロトコルのメソッドを実装します。numberOfItemsInSectionメソッドでは、セクション内に表示するセルの数を返し、cellForItemAtメソッドでは、指定された位置に表示するセルを生成して返します。例えば、CustomCellクラスを使用してセルを表示する場合、以下のように実装します。

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return 10 // セルの数
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CustomCell", for: indexPath) as! CustomCell
    cell.label.text = "Cell \(indexPath.row + 1)"
    return cell
}

上記の例では、10個のセルを表示し、CustomCellクラスのインスタンスを使用してセルを生成しています。また、各セルのラベルには、”Cell 1″、”Cell 2″、”Cell 3″、…というように、インデックスを表示しています。このように、UICollectionViewDataSourceプロトコルのメソッドを実装して、セルを表示することができます。

セルの選択

UICollectionViewDelegateプロトコルのメソッドを実装します。例えば、didSelectItemAtメソッドでは、ユーザーがセルを選択した際に行う処理を実装します。以下は、選択されたセルの背景色を変更する例です。

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    if let cell = collectionView.cellForItem(at: indexPath) {
        cell.backgroundColor = UIColor.blue // 背景色を青に変更
    }
}

上記の例では、didSelectItemAtメソッド内で、選択されたセルのindexPathを取得し、セルの背景色を青に変更しています。また、cellForItem(at:)メソッドを使用して、indexPathに対応するセルを取得しています。このように、UICollectionViewDelegateプロトコルのメソッドを実装することで、セルの選択時に行う処理をカスタマイズすることができます。

スクロールの制御

UICollectionViewDelegateプロトコルのメソッドを実装します。例えば、scrollViewWillEndDraggingメソッドでは、スクロールを停止する直前に行う処理を実装します。以下は、スクロールが一定の範囲外に移動する場合に、スクロールを停止する例です。

func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
    let maxContentOffset = CGPoint(x: 0, y: 1000) // y方向に1000までスクロールできるとする
    if targetContentOffset.pointee.y > maxContentOffset.y {
        targetContentOffset.pointee = maxContentOffset // スクロールを停止する
    }
}

上記の例では、scrollViewWillEndDraggingメソッド内で、スクロールの停止位置を制御しています。targetContentOffsetは、スクロールが停止する位置を示すCGPoint型のポインタです。ここでは、スクロールがy方向に1000までしかできないと仮定して、スクロールがその範囲外に移動する場合に、スクロールを停止するようにしています。targetContentOffset.pointeeに停止位置を代入することで、スクロールを制御することができます。

セルの再利用

UICollectionViewでは、セルの再利用が重要なパフォーマンス上の理由から行われます。例えば、同じ種類のセルが多数存在する場合、毎回新しいセルを作成するのではなく、再利用可能なセルを使いまわすことで、メモリの使用量を減らし、スムーズなスクロールを実現することができます。

再利用可能なセルを作成するには、UICollectionViewCellのサブクラスを作成し、その中にセルの表示内容を実装します。そして、データソースメソッドのcollectionView(_:cellForItemAt:)内で、再利用可能なセルを取得します。以下は、再利用可能なセルの取得方法の例です。

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CellIdentifier", for: indexPath) as! CustomCell
    // セルの表示内容を設定する処理
    return cell
}

上記の例では、dequeueReusableCell(withReuseIdentifier:for:)メソッドを使って、再利用可能なセルを取得しています。withReuseIdentifierには、Storyboard上でセルに付与した識別子を指定します。取得したセルは、as! CustomCellといったキャストを行って、表示内容を設定するCustomCellのインスタンスに変換しています。こうすることで、表示内容を更新するたびに新しいセルを作成するのではなく、再利用可能なセルを使いまわすことができます。

セルの削除・移動

セルの削除・移動は、 UICollectionViewDelegate プロトコルのメソッドを使用して実装されます。 collectionView(_:canEditItemAt:)メソッドを使用して、セルを削除可能にするかどうかを指定し、 collectionView(_:commit:forItemAt:) メソッドを使用して、削除または移動を実行します。たとえば、以下のようなコードで削除と移動を実装することができます。

func collectionView(_ collectionView: UICollectionView, canEditItemAt indexPath: IndexPath) -> Bool {
    return true
}

func collectionView(_ collectionView: UICollectionView, commit editingStyle: UICollectionViewCell.EditingStyle, forItemAt indexPath: IndexPath) {
    if editingStyle == .delete {
        // データソースから対応するアイテムを削除
        dataSource.remove(at: indexPath.item)
        
        // コレクションビューからアイテムを削除
        collectionView.deleteItems(at: [indexPath])
    } else if editingStyle == .move {
        // 移動先のインデックスパスを取得
        let destinationIndexPath = // 移動先のインデックスパス
        
        // データソースからアイテムを取得し、削除
        let item = dataSource.remove(at: indexPath.item)
        
        // データソースにアイテムを挿入
        dataSource.insert(item, at: destinationIndexPath.item)
        
        // コレクションビューのアイテムを移動
        collectionView.moveItem(at: indexPath, to: destinationIndexPath)
    }
}

この例では、 canEditItemAt メソッドを使用して、セルを編集可能にし、 commit メソッドを使用して、セルが削除または移動されたときに、データソースから該当するアイテムを削除または移動し、コレクションビューから対応するアイテムを削除または移動します。

最後に

iOSアプリ開発をしています。
主にSwiftですが、最近は熱が入ってきてFlutterも🦾
色々やってます。もし良かったら見てってください。

1
0
0

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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?