web-dev-qa-db-ja.com

タップ時にUICollectionViewセルの背景を変更

プログラムで作成したUICollectionViewがあります。コレクションビューが次のように動作するようにします。

1. User touches cell
2. Cell background color changes
3. User releases touch
4. Cell background color changes

これは、タップアクションに関連するセレクターが実行される直前に発生する迅速な色の変更であり、コレクションビューを含むViewControllerがスタックからポップされます。

私はこの質問を見ていました: ICollectionViewセルはタップ中に背景を変更します

この目的で使用する方法の概要は次のとおりです。

// Methods for notification of selection/deselection and highlight/unhighlight events.
// The sequence of calls leading to selection from a user touch is:
//
// (when the touch begins)
// 1. -collectionView:shouldHighlightItemAtIndexPath:
// 2. -collectionView:didHighlightItemAtIndexPath:
//
// (when the touch lifts)
// 3. -collectionView:shouldSelectItemAtIndexPath: or -    collectionView:shouldDeselectItemAtIndexPath:
// 4. -collectionView:didSelectItemAtIndexPath: or -collectionView:didDeselectItemAtIndexPath:
// 5. -collectionView:didUnhighlightItemAtIndexPath:

「タッチの開始時」と「タッチの終了時」から上記のメソッドのいずれかを実装するだけでよいと想定しています。しかし、私が何をしても、背景色が変化し、その後も変化したままであるように見えます。以下は、うまくいかなかった試みの例です。

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
 {
   //pop vc 
 }

- (void)collectionView:(UICollectionView *)collectionView didHighlightItemAtIndexPath:(NSIndexPath *)indexPath
{
  UICollectionViewCell* cell = [collectionView cellForItemAtIndexPath:indexPath];
  cell.contentView.backgroundColor = [UIColor redColor];
}

- (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath
{
  UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath];
  cell.contentView.backgroundColor = [UIColor greenColor];
}

これにより、セルの背景色が赤にのみ変更されます。私もこの質問を見ました: ICollectionView Select and Deselect issue と[UICollectionView selectItemAtIndexPath:animated:scrollPosition:]を実装し、didSelectItemAtIndexPath内で呼び出してみましたが、これも機能しませんでした。コレクションビューのデータソースとデリゲートが設定されます。

32
jac300

問題は、highlightの色を変更し、nhighlightの代わりにdeselectに戻すことです

これを単に変更する必要があります。

- (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath
{
  UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath];
  cell.contentView.backgroundColor = [UIColor greenColor];
}

これに:

- (void)collectionView:(UICollectionView *)collectionView didUnhighlightItemAtIndexPath:(NSIndexPath *)indexPath
{
  UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath];
  cell.contentView.backgroundColor = [UIColor greenColor];
}

また、ハイライトが発生するまで少し待ちたくない場合は、コレクションビューのdelaysContentTouchesプロパティをNOに設定する必要があります。

編集:必ず電話してください

[collectionView deselectItemAtIndexPath:indexPath animated:NO];

-didSelectItemAtIndexPathメソッド内

49
Antonio E.

Swift 3バージョン

次の2つのメソッドをView Controllerクラスに追加します。

// change background color when user touches cell
func collectionView(_ collectionView: UICollectionView, didHighlightItemAt indexPath: IndexPath) {
    let cell = collectionView.cellForItem(at: indexPath)
    cell?.backgroundColor = UIColor.red
}

// change background color back when user releases touch
func collectionView(_ collectionView: UICollectionView, didUnhighlightItemAt indexPath: IndexPath) {
    let cell = collectionView.cellForItem(at: indexPath)
    cell?.backgroundColor = UIColor.green
}

Swiftで基本的なコレクションビューを設定する方法については、 here をご覧ください。

31
Suragch

編集:Swiftで回答

var selectedIndex = Int ()

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

    cell.backgroundColor = selectedIndex == indexPath.row ? UIColor.green : UIColor.red

    return cell
}

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
{
    selectedIndex = indexPath.row

    self.yourCollctionView.reloadData()
}
8
Abirami Bala

これが私の解決策です。そして、私はそれが本当にうまくいくと確信しています。
セルを強調表示する3つのメソッドを提供します(selectedBackgroundView、_cell.contentView_に色付けし、特別な領域に色付けします)。

使い方:
1。 BaseCollectionViewCellを継承し、何もしません。
2。 specialHighlightedArea = UIView()およびcontentView.addSubView(specialHighlightedArea)を継承して設定し、レイアウトするか、自動レイアウトを使用するための制約を追加します。
3。ハイライト効果が必要ない場合は、UICollectionViewDelegateで定義された 'shouldHighlightItemAtIndexPath'という名前のメソッドを記述してfalseを返すか、_cell.shouldTintBackgroundWhenSelected = false_を設定して_specialHighlightedArea = nil_を設定し、superViewから削除します。 。

_/// same with UITableViewCell's selected backgroundColor
private let highlightedColor = UIColor(rgb: 0xD8D8D8) 

/// you can make all your collectionViewCell inherit BaseCollectionViewCell
class BaseCollectionViewCell: UICollectionViewCell {

    /// change it as you wish when or after initializing
    var shouldTintBackgroundWhenSelected = true

    /// you can give a special view when selected
    var specialHighlightedArea: UIView? 

    // make lightgray background display immediately(使灰背景立即出现)
    override var isHighlighted: Bool { 
        willSet {
            onSelected(newValue)
        }
    }

    // keep lightGray background until unselected (保留灰背景)
    override var isSelected: Bool { 
        willSet {
            onSelected(newValue)
        }
    }

    func onSelected(_ newValue: Bool) {
        guard selectedBackgroundView == nil else { return }
        if shouldTintBackgroundWhenSelected {
            contentView.backgroundColor = newValue ? highlightedColor : UIColor.clear
        }
        if let area = specialHighlightedArea {
            area.backgroundColor = newValue ? UIColor.black.withAlphaComponent(0.4) : UIColor.clear
        }
    }
}

extension UIColor {
    convenience init(rgb: Int, alpha: CGFloat = 1.0) {
        self.init(red: CGFloat((rgb & 0xFF0000) >> 16) / 255.0, green: CGFloat((rgb & 0xFF00) >> 8) / 255.0, blue: CGFloat(rgb & 0xFF) / 255.0, alpha: alpha)
    }
}
_
4
DawnSong

シンプルなバイナリロジックソリューション。 Swift 3 and 4:

func collectionView(_ collectionView: UICollectionView, didSelectItemAt
    indexPath: IndexPath) {
    let cell = collectionView.cellForItem(at: indexPath) as! CategoryCell
    let lastCellColor = cell.backgroundColor
    if cell.isSelected {cell.backgroundColor = .green} else {cell.backgroundColor = lastCellColor}
}
0
Brian