Cambiar el background de UICollectionView Cell on Tap

Tengo un UICollectionView que he creado mediante progtwigción. Me gustaría que la vista de colección se comporte de la siguiente manera:

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

Este debería ser un cambio de color rápido que ocurre justo antes de que se ejecute el selector relacionado con la acción de toque en el que el controller de vista que contiene la vista de la colección sale de la stack.

He estado mirando esta pregunta: background de cambio de celda UICollectionView mientras presiono

en el que se encuentra el siguiente resumen de los methods a utilizar para este fin:

 // 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: 

Estoy asumiendo que solo necesito implementar uno de los methods anteriores desde "cuando comienza el tacto" y "cuando el tacto finaliza". Pero no importa lo que haga, parece que un color de background cambia y luego permanece cambiado. Aquí hay un ejemplo de algo que intenté que no funcionó:

 - (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 networkingColor]; } - (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath { UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath]; cell.contentView.backgroundColor = [UIColor greenColor]; } 

Esto da como resultado que el color de background de la celda solo se cambie a rojo. También miré esta pregunta: UICollectionView Seleccione y deselect el problema y trató de implementar [UICollectionView selectItemAtIndexPath: animated: scrollPosition:] y llamarlo dentro de didSelectItemAtIndexPath, pero esto tampoco funcionó. La fuente de datos y el delegado de la vista de recostackción están configurados.

El problema es que estás cambiando el color en resaltado y cambiándolo de nuevo en deseleccionarlo en lugar de hacerlo en unhighlight

Simplemente debe cambiar esto:

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

a esto:

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

Además, si no desea esperar un poco antes de que delaysContentTouches su resaltado, debe establecer la propiedad delaysContentTouches de la vista de recostackción en NO

Edit: también asegúrate de llamar

 [collectionView deselectItemAtIndexPath:indexPath animated:NO]; 

dentro del método -didSelectItemAtIndexPath

Versión Swift 3

Agregue los dos methods siguientes a su class de controller de vista:

 // change background color when user touches cell func collectionView(_ collectionView: UICollectionView, didHighlightItemAt indexPath: IndexPath) { let cell = collectionView.cellForItem(at: indexPath) cell?.backgroundColor = UIColor.networking } // 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 } 

Vea aquí la ayuda para configurar una vista de colección básica en Swift.

Esta es mi solucion Y estoy seguro de que realmente funciona.
Proporciono tres methods para resaltar una celda (selectedBackgroundView, cell.contentView y tinte un área especial).

Cómo utilizar:
1. simplemente henetworkingar BaseCollectionViewCell y no hacer nada;
2. henetworkingar y establecer specialHighlightedArea = UIView() , y contentView.addSubView(specialHighlightedArea) , luego distribuirlo o agregar restricciones para usar Auto Layout;
3. Si no necesita resaltar el efecto, simplemente escriba un método llamado 'shouldHighlightItemAtIndexPath' definido por UICollectionViewDelegate y haga que devuelva false, o establezca cell.shouldTintBackgroundWhenSelected = false y configure specialHighlightedArea = nil y elimínelo de 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(networking: CGFloat((rgb & 0xFF0000) >> 16) / 255.0, green: CGFloat((rgb & 0xFF00) >> 8) / 255.0, blue: CGFloat(rgb & 0xFF) / 255.0, alpha: alpha) } } 

Edición: respuesta en Swift 3

 var selectedIndex = Int () func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell if selectedIndex == indexPath.row { cell.backgroundColor = UIColor.green } else { cell.backgroundColor = UIColor.networking } return cell } func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { selectedIndex = indexPath.row self.yourCollctionView.reloadData() }