在CollectionView上滑动即可删除

我试图复制滑动删除函数,如在邮件tableview中。 只有这一次,我需要在collectionview上构build它,但是我有点困难。 这是一个水平滚动列表刷卡删除。 我已经得到了刷卡工作,但很难搞清楚我需要如何设置刷卡删除/点击删除或忽略function。

它看起来像下面这样: 删除图像

所以我使用以下collectionview:

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 } 

我的自定义video单元包含一个图像,下面有删除button。 所以如果你向上滑动图像,popup删除button。 不知道这是如何做到这一点的正确方法:

 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") } } 

我正在使用以下逻辑:

 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. } } 

但问题从那里开始。 一旦我的单元格在collectionview界限之外,我就无法再访问它了。 我仍然想要进一步将其删除。 我只能通过在删除button上滑动来做到这一点,但我希望它上面的Imageview也是可以滑动的。 或者如果我点击收集视图以外的图像,它应该滑回到行,而不是删除它。

如果我增加collectionview界限,我可以防止这个问题,但比我还可以刷卡删除单元格的可见高度之外。 这是由collectionview内的tapLocation引起的,并检测到一个indexPath。 一些我不想要的东西。 我只需要向上滑动即可在collectionview的单元格上工作。

此外,button和图像互相干扰,因为我无法区分它们。 他们都在同一个单元格,所以我想知道是否应该有单元格中的删除button。 或者我应该把它放在哪里? 我也可以做出两个button,并根据状态禁用用户交互,但不知道如何结束。

为了我自己的好奇,我试着重复你正在做的事情,并把它做好。 和我的设置方式不一样,因为我没有使用pan,但是你说你已经有了这个部分,而且没有太多的时间花在这个上面。 潘显然是使交互性更稳固的解决scheme,但需要更长的时间来计算,但效果和处理,应该没有太大的差别。

为了解决无法在单元格外滑动的问题,我决定检查点是否在滑动矩形中,这是非滑动矩形高度的两倍,如下所示:

  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!]) } 

我创build了一个带有注释的演示: https : //github.com/imbue11235/swipeToDeleteCell

无论如何,我希望它能帮助你!

因此,如果您希望滑动手势识别器在其集合视图之外继续进行logging移动,则需要将其附加到集合视图的父级,以便将其绑定到用户可以滑动的整个区域。

这确实意味着你将会在集合视图之外获得更多的东西,但是你可以很容易地忽略那些使用任何技术的人。

要注册删除button轻敲,您需要在button上调用addTarget:action:forControlEvents:

我会保持你的单元格,与图像和button在一起。 pipe理起来要容易得多,而且他们都在一起。

要pipe理上下移动图像,我会看看使用转换,或NSLayoutConstraint。 然后,您只需调整一个值,使其与用户滑动同步上下移动即可。 没有搞乱帧。