在CollectionView上滑动以删除
我正在尝试复制滑动以删除函数,就像在mail tableview中一样。只有这次我需要在收集视图上构建它,但我有点困难。这是一个水平滚动列表,可以向上滑动删除。我已经完成了向上滑动,但很难搞清楚我需要如何设置滑动以删除/点按以删除或忽略功能。
I'm trying to replicate the swipe to delete function like in the mail tableview. Only this time I need to build it on a collectionview but I'm having a bit of a hard time. It's a horizontal scrolling list with a swipe up to delete. I already got the swipe up working but having a hard time figuring out how I need to setup the swipe to delete / tap to delete or ignore functionality.
它看起来像是以下:
It looks like the following:
所以我使用以下集合视图:
So I'm using the following 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
}
我的自定义视频广告包含一张图片,下面是删除按钮。因此,如果您向上滑动图像,则会弹出删除按钮。不确定这是否是正确的方法:
My custom videocell contains one image and below that there is the delete button. So if you swipe the image up the delete button pops up. Not sure if this is the right way on how to do it:
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边界之外,我就再也无法访问它了。我仍然想进一步刷它以删除它。我只能通过在删除按钮上滑动来完成此操作,但我希望它上面的Imageview也可以刷卡。或者如果我点击集合视图外的图像,它应该滑回到行中而不是删除它。
But the problem starts there. As soon as my cell is outside the collectionview bounds I can't access it anymore. I still want to swipe it further to remove it. I can only do this by swiping on the delete button, but I want the Imageview above it to be swipeable as well. Or if I tap the image outside the collectionview it should slide back into the line and not delete it.
如果我增加了集合视图边界我可以防止这个问题但是我也可以滑动以移除细胞外可见高度。这是由collectionview中的tapLocation引起的,它检测到indexPath。我不想要的东西。我想要向上滑动只能在集合视图的单元格上工作。
If I increase the collectionview bounds I can prevent this problem but than I can also swipe to remove outside the cell's visible height. This is caused by the tapLocation that is inside the collectionview and detects an indexPath. Something that I don't want. I want the swipe up only to work on a collectionview's cell.
此外,按钮和图像相互干扰,因为我无法区分它们。它们都在同一个单元格中,这就是为什么我想知道我是否应该在单元格中有删除按钮。或者我应该把它放在哪里?我也可以制作两个按钮并根据状态禁用用户交互,但不确定最终会如何结束。
Also the button and the image interfere with each other because I cannot distinguish them. They are both in the same cell so that's why I'm wondering if I should have the delete button in the cell at all. Or where should I place it otherwise? I could also make two buttons out of it and disable user interaction depending on state, but not sure how that would end up.
为了我自己的好奇心,我试图复制你想要做的事情,并让它以某种方式工作。它与我的设置刷卡手势的方式不同,因为我没有使用平底锅,但是你说你已经有了这个部分,并且没有花太多时间在它上面。 Pan显然是使它具有交互性的更可靠的解决方案,但需要花费更长的时间来计算,但它的效果和处理方式与我的例子不同。
For my own curiosity's sake I tried to make a replicate of what you're trying to do, and got it to work somehow good. It differs from yours in the way I setup the swipe gestures as I didn't use pan, but you said you already had that part, and haven't spend too much time on it. Pan is obviously the more solid solution to make it interactive, but takes a little longer to calculate, but the effect and handling of it, shouldn't differ much from my example.
为了解决无法在单元格外滑动的问题,我决定检查点是否在滑动的矩形中,这是非滑动矩形的两倍,如下所示:
To resolve the issue not being able to swipe outside the cell I decided to check if the point was in the swiped rect, which is twice the height of the non-swiped rect like this:
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!])
}
我用commen创建了一个演示ts: https://github.com/imbue11235/swipeToDeleteCell
I created a demonstration with comments: https://github.com/imbue11235/swipeToDeleteCell
我希望无论如何它能帮到你!
I hope it helps you in anyway!