ios - swipecellkit - Desliza para eliminar en CollectionView
swipecellkit swift 3 (2)
Por lo tanto, si desea que el reconocedor de gestos de swipes continúe grabando el movimiento cuando están fuera de su vista de colección, debe adjuntarlo al elemento primario de la vista de colección, de modo que esté limitado al área completa donde el usuario puede deslizar.
Eso significa que obtendrás swipes para cosas que están fuera de la vista de colección, pero puedes ignorar fácilmente aquellas que utilicen cualquier número de técnicas.
Para registrar los toques de eliminación, deberá llamar a addTarget: action: forControlEvents: en el botón
Mantendría la celda como la tienes, con la imagen y el botón juntos. Será mucho más fácil de manejar, y pertenecen juntos.
Para gestionar mover la imagen hacia arriba y hacia abajo, vería usar una transformación o una NSLayoutConstraint. Luego, solo tiene que ajustar un valor para que se mueva hacia arriba y hacia abajo en sincronización con los movimientos del usuario. No te metas con los marcos.
Estoy intentando replicar la función de deslizar para eliminar como en la vista de tabla de correo. Solo que esta vez necesito crearlo en una vista de colección, pero me está costando un poco. Es una lista de desplazamiento horizontal con un barrido hacia arriba para eliminar. Ya tengo el barrido funcionando, pero me resulta difícil descubrir cómo debo configurar el barrido para eliminar / tocar para eliminar o ignorar la funcionalidad.
Así que estoy usando la siguiente vista de colección:
func buildCollectionView() {
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.minimumInteritemSpacing = 0;
layout.minimumLineSpacing = 4;
collectionView = UICollectionView(frame: CGRect(x: 0, y: screenSize.midY - 120, width: screenSize.width, height: 180), collectionViewLayout: layout)
collectionView.dataSource = self
collectionView.delegate = self
collectionView.register(VideoCell.self, forCellWithReuseIdentifier: "videoCell")
collectionView.showsHorizontalScrollIndicator = false
collectionView.showsVerticalScrollIndicator = false
collectionView.contentInset = UIEdgeInsetsMake(0, 20, 0, 30)
collectionView.backgroundColor = UIColor.white()
collectionView.alpha = 0.0
//can swipe cells outside collectionview region
collectionView.layer.masksToBounds = false
swipeUpRecognizer = UIPanGestureRecognizer(target: self, action: #selector(self.deleteCell))
swipeUpRecognizer.delegate = self
collectionView.addGestureRecognizer(swipeUpRecognizer)
collectionView.isUserInteractionEnabled = true
}
Mi videocélula personalizada contiene una imagen y debajo está el botón de eliminar. Así que si pasas la imagen hacia arriba, aparecerá el botón Eliminar. No estoy seguro de si esta es la forma correcta de hacerlo:
class VideoCell : UICollectionViewCell {
var deleteView: UIButton!
var imageView: UIImageView!
override init(frame: CGRect) {
super.init(frame: frame)
deleteView = UIButton(frame: CGRect(x: 0, y: 0, width: frame.size.width, height: frame.size.height))
deleteView.contentMode = UIViewContentMode.scaleAspectFit
contentView.addSubview(deleteView)
imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: frame.size.width, height: frame.size.height))
imageView.contentMode = UIViewContentMode.scaleAspectFit
contentView.addSubview(imageView)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Y estoy usando la siguiente lógica:
func deleteCell(sender: UIPanGestureRecognizer) {
let tapLocation = sender.location(in: self.collectionView)
let indexPath = self.collectionView.indexPathForItem(at: tapLocation)
if velocity.y < 0 {
//detect if there is a swipe up and detect it''s distance. If the distance is far enough we snap the cells Imageview to the top otherwise we drop it back down. This works fine already.
}
}
Pero el problema comienza allí. Tan pronto como mi celular esté fuera de los límites de la vista de la colección, no podré acceder más. Todavía quiero deslizarlo más para eliminarlo. Solo puedo hacer esto al deslizar el botón de eliminar, pero quiero que la vista de imagen de arriba también se pueda deslizar. O si toco la imagen fuera de la colección, debería volver a la línea y no borrarla.
Si incremento los límites de la vista de colección, puedo evitar este problema pero también puedo deslizar para eliminar fuera de la altura visible de la celda. Esto se debe a que tapLocation está dentro de la vista de recopilación y detecta una indexPath. Algo que no quiero. Quiero que el barrido solo funcione en el celular de una vista de colección.
También el botón y la imagen interfieren entre sí porque no puedo distinguirlos. Ambos están en la misma celda, por eso me pregunto si debería tener el botón de eliminar en la celda. ¿O dónde debería colocarlo de otra manera? También podría hacer dos botones y deshabilitar la interacción del usuario según el estado, pero no estoy seguro de cómo terminaría eso.
Por mi propia curiosidad, traté de hacer una réplica de lo que intentas hacer y funcionó de alguna manera. Difiere de la tuya en la forma en que configuro los gestos de deslizamiento, ya que no utilicé pan, pero dijiste que ya tenías esa parte y que no le dedicaste mucho tiempo. Pan es obviamente la solución más sólida para hacerla interactiva, pero toma un poco más de tiempo calcularla, pero el efecto y el manejo de la misma no deberían diferir mucho de mi ejemplo.
Para resolver el problema al no poder deslizar fuera de la celda, decidí verificar si el punto estaba en el rect barrido, que es el doble de la altura del rect no barrido de esta manera:
let cellFrame = activeCell.frame
let rect = CGRectMake(cellFrame.origin.x, cellFrame.origin.y - cellFrame.height, cellFrame.width, cellFrame.height*2)
if CGRectContainsPoint(rect, point) {
// If swipe point is in the cell delete it
let indexPath = myView.indexPathForCell(activeCell)
cats.removeAtIndex(indexPath!.row)
myView.deleteItemsAtIndexPaths([indexPath!])
}
Creé una demostración con comentarios: https://github.com/imbue11235/swipeToDeleteCell
Espero que te ayude de todos modos!