Quizás, usar UILongPressGestureRecognizer es la solución más extendida. Pero me encuentro con dos problemas molestos:
- a veces este reconocedor funciona de manera incorrecta cuando movemos nuestro toque;
- El reconocedor intercepta otras acciones táctiles, por lo que no podemos usar las devoluciones de llamada resaltadas de nuestro UICollectionView de manera adecuada.
Permítanme sugerir uno un poco de fuerza bruta, pero funcionando como se requiere sugerencia:
Declarando una descripción de devolución de llamada para un clic largo en nuestra celda:
typealias OnLongClickListener = (view: OurCellView) -> Void
Extendiendo UICollectionViewCell con variables (podemos llamarlo OurCellView, por ejemplo):
/// To catch long click events.
private var longClickListener: OnLongClickListener?
/// To check if we are holding button pressed long enough.
var longClickTimer: NSTimer?
/// Time duration to trigger long click listener.
private let longClickTriggerDuration = 0.5
Añadiendo dos métodos en nuestra clase de celda:
/**
Sets optional callback to notify about long click.
- Parameter listener: A callback itself.
*/
func setOnLongClickListener(listener: OnLongClickListener) {
self.longClickListener = listener
}
/**
Getting here when long click timer finishs normally.
*/
@objc func longClickPerformed() {
self.longClickListener?(view: self)
}
Y eventos táctiles predominantes aquí:
/// Intercepts touch began action.
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
longClickTimer = NSTimer.scheduledTimerWithTimeInterval(self.longClickTriggerDuration, target: self, selector: #selector(longClickPerformed), userInfo: nil, repeats: false)
super.touchesBegan(touches, withEvent: event)
}
/// Intercepts touch ended action.
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
longClickTimer?.invalidate()
super.touchesEnded(touches, withEvent: event)
}
/// Intercepts touch moved action.
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
longClickTimer?.invalidate()
super.touchesMoved(touches, withEvent: event)
}
/// Intercepts touch cancelled action.
override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
longClickTimer?.invalidate()
super.touchesCancelled(touches, withEvent: event)
}
Luego, en algún lugar del controlador de nuestra vista de colección declarando el oyente de devolución de llamada:
let longClickListener: OnLongClickListener = {view in
print("Long click was performed!")
}
Y finalmente en cellForItemAtIndexPath configurando la devolución de llamada para nuestras celdas:
/// Data population.
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath)
let castedCell = cell as? OurCellView
castedCell?.setOnLongClickListener(longClickListener)
return cell
}
Ahora podemos interceptar acciones de clic largo en nuestras celdas.
UICollectionViewCell* cell = [self.collectionView cellForItemAtIndexPath:indexPath];
referencia aquí espero que todo esto merezca un premio de respuesta correcta: D