没有实现您想要的本机功能。如果我理解正确,您会想要折叠整个行,然后开始拖动“标题”。如果您想自己执行此操作,我建议您从在标题按钮上触发的平移手势识别器开始。
手势应该比较明显。从标题开始后,您需要在表格视图中使用locationIn 跟踪位置。
要折叠行,您只需使用适当的动画修改表格视图单元格,例如:
tableView.beginUpdates()
tableView.deleteSections([myIndexPath], with: .top) // Maybe experiment with animation type
// Modify whatever you need to correspond this change in the data source
tableView.endUpdates()
由于您将删除该部分,因此您还将删除具有手势识别器的视图(标题)。这意味着直接将手势添加到表格视图或它的超级视图可能会更好。只有在按下标题上的这些按钮之一时,您才需要强制它触发。你可以对它有所了解here。其余部分不受此更改的影响。
此时您可能需要创建一个额外的视图来代表您的部分堆栈并跟随您的手指。如果您将其添加为子视图并在其父视图中使用平移手势识别器locationIn 操作它的中心,这应该很容易:
movableSectionView.center = panGestureRecognizer.location(in: movableSectionView.superview!)
所以到目前为止,您应该能够抓取一个折叠所有单元格的部分,并能够拖动“部分堆栈”视图。现在您需要检查您的手指在表格视图中的位置,以了解该部分的放置位置。这有点痛苦,但可以通过visibleCells 和tableView.indexPath(for: ) 来完成:
func indexPathForGestureRecognizer(_ recognizer: UIGestureRecognizer) -> IndexPath {
let coordinateView: UIView = tableView.superview! // This can actually be pretty much anything as long as it is in hierarchy
let y = recognizer.location(in: coordinateView).y
if let hitCell = tableView.visibleCells.first(where: { cell in
let frameInCoordinateView = cell.convert(cell.bounds, to: coordinateView)
return frameInCoordinateView.minY >= y && frameInCoordinateView.maxY <= y
}) {
// We have the cell at which the finger is. Retrieve the index path
return tableView.indexPath(for: hitCell) ?? IndexPath(row: 0, section: 0) // This should always succeed but just in case
} else {
// We may be out of bounds. That may be either too high which means above the table view otherwise too low
if recognizer.location(in: tableView).y < 0.0 {
return IndexPath(row: 0, section: 0)
} else {
guard tableView.numberOfSections > 0 else {
return IndexPath(row: 0, section: 0) // Nothing in the table view at all
}
let section = tableView.numberOfSections-1
return IndexPath(row: tableView.numberOfRows(inSection: section), section: section)
}
}
}
一旦手势识别器结束,您就可以使用此方法获取您将项目放入的部分。所以只是:
tableView.beginUpdates()
// Modify whatever you need to correspond this change in the data source
tableView.insertSections([indexPathForGestureRecognizer(panGestureRecognizer).section], with: .bottom)
tableView.endUpdates()
这对于重新排序基本上已经足够了,但是您可能希望在表格视图中显示被拖动部分的位置。就像在将放入堆栈的部分的末尾有一个占位符一样。这应该相对容易,只需添加然后移动一个额外的占位符单元格,重复使用 indexPathForGestureRecognizer 来获得它的位置。
玩得开心。