プログラムで作成した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内で呼び出してみましたが、これも機能しませんでした。コレクションビューのデータソースとデリゲートが設定されます。
問題は、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メソッド内
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 をご覧ください。
編集: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()
}
これが私の解決策です。そして、私はそれが本当にうまくいくと確信しています。
セルを強調表示する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)
}
}
_
シンプルなバイナリロジックソリューション。 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}
}