質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.79%

collectionView セル選択時に色を変える

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,025

score 17

作りたいもの
collectionViewを使ってカードゲームのようなものを作っています

実現したいこと
collectionViewのCell(カードの表示ように使っている)をタップした際に、選択しているCellの色が変わるようにしたいのですがうまくいきません(触れている時のみに色が変化している状態でも、次のCellを選択するまで色が変わった状態でもどちらでも構いません)

試したこと
いくつかの記事を参考に

 func collectionView(collectionView: UICollectionView, didHighlightItemAtIndexPath indexPath: IndexPath) {
        if collectionView == myCollectionView {
            let cell = myCollectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath)
            cell.backgroundColor = UIColor.red
        } else {
            let cell = enemyCollectionView.dequeueReusableCell(withReuseIdentifier: "NCell", for: indexPath)
            cell.backgroundColor = UIColor.red
        }

       }


のように書いてみましたが、セルをタップしてみても色は変わりませんでした

どのようにすればうまくいくのか教えていただきたいです

こちらは、collectionViewに関係のなさそうなものを省いたコードです

コード
//
//  ViewController.swift
//  GuessNum
//
//  Created by Apple on 2020/05/08.
//  Copyright © 2020 ryotaro.tsuji. All rights reserved.
//

import UIKit

class ViewController: UIViewController,UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout {


    //    CollectionViewの接続
    @IBOutlet weak var myCollectionView: UICollectionView!
    @IBOutlet weak var enemyCollectionView: UICollectionView!
    @IBOutlet weak var enemyGuessButton: UIButton!


    //    山札の配列
    var numArray = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]
    //    味方札の配列
    var myNumArray:[Int] = []
    //    敵札の配列
    var enemyNumArray:[Int] = []
    //    ターンのカウント
    var addTurnCount = 0
    var checkTurnCount = 0
    var forCheckCount = 0
    // TextField
    @IBOutlet weak var myTextField: UITextField!
    @IBOutlet weak var enemyTextField: UITextField!
    //    CollectionView表示用の数字
    var myCellSetNum = 0
    var enemyCellSetNum = 0
    //    タップしたセルの値
    var tapedCellNum = 0
    //    的中した数字の配列
    var hitNumArray:[Int] = []




    override func viewDidLoad() {
        super.viewDidLoad()


        self.view.backgroundColor = UIColor(red: 0, green: 0.7, blue: 0, alpha: 1)


        //        山札をシャッフル
        numArray.shuffle()


        //        CollectionViewのdelegate
        myCollectionView.delegate = self
        myCollectionView.dataSource = self
        enemyCollectionView.delegate = self
        enemyCollectionView.dataSource = self

        //       CollectionViewのレイアウト
        let mylayout = UICollectionViewFlowLayout()
        mylayout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
        mylayout.minimumInteritemSpacing = 1
        mylayout.minimumLineSpacing = 1
        myCollectionView.collectionViewLayout = mylayout


        let enemyLayout = UICollectionViewFlowLayout()
        enemyLayout.sectionInset = UIEdgeInsets(top: 1, left: 1, bottom: 1, right: 1)
        enemyLayout.minimumInteritemSpacing = 1
        enemyLayout.minimumLineSpacing = 1
        enemyCollectionView.collectionViewLayout = enemyLayout

        //        collectionViewの背景画像

        self.myCollectionView.backgroundColor = UIColor(red: 0, green: 0.7, blue: 0, alpha: 1)
        self.enemyCollectionView.backgroundColor = UIColor(red: 0, green: 0.7, blue: 0, alpha: 1)
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {

        if collectionView == myCollectionView {
            return myNumArray.count
        } else if collectionView == enemyCollectionView {
            return enemyNumArray.count
        } else {
            return 0
        }
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        if collectionView == self.myCollectionView {
            let cell = myCollectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath)

            let label = cell.contentView.viewWithTag(1) as! UILabel
            myCellSetNum = myNumArray[indexPath.row]


            let evenOrOdd = myCellSetNum % 2
            switch evenOrOdd {
            case 0:

                label.textColor = UIColor.white
                cell.backgroundColor = UIColor.black
            case 1:

                label.textColor = UIColor.black
                cell.backgroundColor = UIColor.white
            default:
                label.text = "?"
            }


            let checkCellNum = hitNumArray.firstIndex(of: myNumArray[indexPath.row])

            if checkTurnCount == 1 {
                let evenOrOdd = myCellSetNum % 2
                switch evenOrOdd {
                case 0:
                    let myCellSetString = "\(myCellSetNum / 2)"
                    label.text = myCellSetString

                case 1:
                    let myCellSetString = "\((myCellSetNum + 1) / 2)"
                    label.text = myCellSetString

                default:
                    label.text = "?"
                }

            } else {
                if let no = checkCellNum {

                    let evenOrOdd = myCellSetNum % 2
                    switch evenOrOdd {
                    case 0:
                        let myCellSetString = "\(myCellSetNum / 2)"
                        label.text = myCellSetString

                    case 1:
                        let myCellSetString = "\((myCellSetNum + 1) / 2)"
                        label.text = myCellSetString

                    default:
                        label.text = "?"
                    }

                } else {
                    let label = cell.contentView.viewWithTag(1) as! UILabel
                    label.text = "?"
                }
            }
            print(myCellSetNum)
            return cell

        } else {
            let cell = enemyCollectionView.dequeueReusableCell(withReuseIdentifier: "NCell", for: indexPath)

            let label = cell.contentView.viewWithTag(1) as! UILabel
            enemyCellSetNum = enemyNumArray[indexPath.row]
            let evenOrOdd = enemyCellSetNum % 2
            switch evenOrOdd {
            case 0:

                label.textColor = UIColor.white
                cell.backgroundColor = UIColor.black
            case 1:

                label.textColor = UIColor.black
                cell.backgroundColor = UIColor.white
            default:
                label.text = "?"
            }


            let checkCellNum = hitNumArray.firstIndex(of: enemyNumArray[indexPath.row])

            if checkTurnCount == 2 {
                let evenOrOdd = enemyCellSetNum % 2
                switch evenOrOdd {
                case 0:
                    let myCellSetString = "\(enemyCellSetNum / 2)"
                    label.text = myCellSetString

                case 1:
                    let enemyCellSetString = "\((enemyCellSetNum + 1) / 2)"
                    label.text = enemyCellSetString

                default:
                    label.text = "?"
                }
            } else {
                if let no = checkCellNum {

                    let evenOrOdd = enemyCellSetNum % 2
                    switch evenOrOdd {
                    case 0:
                        let myCellSetString = "\(enemyCellSetNum / 2)"
                        label.text = myCellSetString

                    case 1:
                        let enemyCellSetString = "\((enemyCellSetNum + 1) / 2)"
                        label.text = enemyCellSetString

                    default:
                        label.text = "?"
                    }
                } else {
                    let label = cell.contentView.viewWithTag(1) as! UILabel
                    label.text = "?"
                }
            }
            return cell

        }

    }


    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

        if collectionView == self.myCollectionView {
            tapedCellNum = myNumArray[indexPath.row]

        } else {
            tapedCellNum = enemyNumArray[indexPath.row]

        }
        print(tapedCellNum)
    }


    //   セルのレイアウトを設定
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

        let width = UIScreen.main.bounds.size.width

        let widthcellSize : CGFloat = (width - 11) / 14
        let heightcellSize : CGFloat = widthcellSize * 2
        return CGSize(width: widthcellSize, height: heightcellSize)
    }


       }
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

イメージ説明

CellForItemAtn内でUICollectionViewselectedBackgroundViewに用意したカスタムViewを突っ込んで、
UICollectionViewのallowSelection/allowsMultipleSelectionプロパティを設定してあげれば、あとは何も記述しなくともよしなにやってくれます。

私はこの方法が良いと思います。

import UIKit

// 背景用のView
class CellBgView: UIView {

    init(num: Int) {
        super.init(frame: CGRect.zero)
        // 偶数と奇数で色変えてみよう
        backgroundColor = num % 2 == 0 ? .red : .orange
    }

    required init(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

class ViewController: UIViewController{

    var array = [Int](0...30)

    @IBOutlet weak var collectionView: UICollectionView!

    private let sectionInsets = UIEdgeInsets(top: 20.0, left: 10.0, bottom: 20.0, right: 10.0)
    private let itemsPerRow: CGFloat = 3

    override func viewDidLoad() {
        super.viewDidLoad()

        // 選択の条件を設定する
        //collectionView.allowsSelection = true
        collectionView.allowsMultipleSelection = true
    }
}

extension ViewController: UICollectionViewDataSource {

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

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! CustomCell
        cell.label.text = String(format: "%02d", indexPath.row)
        // ここで背景を設定するだけ
        cell.selectedBackgroundView = CellBgView(num: indexPath.row)
        return cell
    }

}

class CustomCell: UICollectionViewCell {

    @IBOutlet weak var label: UILabel!

}


// あとはレイアウト用です

extension ViewController: UICollectionViewDelegateFlowLayout {

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

        let paddingSpace = sectionInsets.left * (itemsPerRow + 1)
        let availableWidth = UIScreen.main.bounds.width - paddingSpace
        let withPerItem = availableWidth / itemsPerRow

        //cellの大きさを返す
        return CGSize(width: withPerItem, height: withPerItem)
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {

        return sectionInsets

    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {

        return sectionInsets.left

    }
}

選択されているセルのインデックスパスは、indexPathsForSelectedItemsとかでとれます

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/05/17 23:37

    ありがとうございます
    上記の方法でうまくいきました

    また自分でも色々と調べてみて
    cellForItemAt 内に
    let selectedBGView = UIView(frame: cell.frame)
    selectedBGView.backgroundColor = .blue
    cell.selectedBackgroundView = selectedBGView
    のような記述をすることでもうまくいきそうです
    本当にありがとうございました

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.79%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る