所以我正在尝试为我的(许多)Drag&Drop
实现自定义collectionView
功能。 IOS 11中新的拖放功能很好,但是我不喜欢您不能真正访问它太多(例如,您不能调整长按手势识别器)。
还有interactive reordering
的集合视图,它们都带有不错的方法。但是我需要能够在不同的collectionViews
之间移动项目。我认为您无法通过交互式重新排序来做到这一点。
因此(并且因为我想学习它),我想实现自己的拖放。
移动单元格的能力应该是相当可行的(快照单元格,将快照视图添加到ViewController
并不断检查其位置以查找可能的放置位置)。但是,还有一个我尚不知道如何解决的大问题:布局。
每当我将鼠标悬停在collectionView
上时,都应在其中创建一个间隙,将其他单元格移开,以便为将要放置在那里的单元格腾出空间。我的天真做法是这样的:
class MyCustomLayout: UICollectionViewLayout {
... (other basic stuff, not relevant)
override func prepare() {
// cache contains the cached layout attributes
guard cache.isEmpty, let collectionView = collectionView else {
return
}
// I'm using IGListKit, so every cell is in its own section in my case
for section in 0..<collectionView.numberOfSections {
let indexPath = IndexPath(item: 0, section: section)
// If a gap has been set, just make the current offset (contentWidth) bigger to
// simulate a "missing" item, which creates a gap
if gap == indexPath {
contentWidth += 200 + cellPadding // cellPadding is just a CGFloat you can set
}
// contentWidth is used as x origin
let frame = CGRect(x: contentWidth, y: 0, width: 200, height: contentHeight)
contentWidth += frame.width + cellPadding
let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath)
attributes.frame = frame
cache.append(attributes)
}
}
...
public func makeAGap(at indexPath: IndexPath) {
gap = indexPath
invalidateLayout() // resets cache, and sets contentWidth = 0 to be "refilled"
}
}
这基本上是这样的:我可以调用layout.makeAGap(...)
,这会使布局无效并设置gap
属性。在prepare()
中,我检查此gap
的索引路径。找到后,我只需将下一个单元格的原点向右移一点,以创建一个完美的间隙。
这正在工作。但是,没有“将细胞移开”动画。它只是淡出到新计算的布局。不好看。
有没有一种方法可以让细胞移动到新的位置,而不仅仅是褪色?我对UICollectionViewLayout
并不十分熟悉,因此这可能是不可能的。如果没有,那么手动创建这种差距的替代方法是什么?
感谢您的帮助:)