Это решение здесь будет работать аналогично приложению «Напоминания» в OSX, которое позволяет изменять порядок ячеек, удерживая и перетаскивая их в любом месте.
Я создал подкласс UITableView, который позволяет перетаскивать и изменять порядок ячеек без необходимости использовать editing
или использовать стандартные маркеры изменения порядка.
Основная идея заключается в том, что я использую касания, которые начинались, и касания заканчивались, чтобы определить, какая ячейка была нажата, затем я создаю фальшивый вид, который на самом деле является просто скриншотом касавшегося вами вида, и перемещаю его назад и вперед, меняя местамиклетки на заднем плане.Когда пользователь отпускает, я показываю исходный вид.
class ReorderTableView: UITableView {
var customView:UIImageView?
var oldIndexPath:NSIndexPath?
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
guard let touch1 = touches.first else{
return
}
oldIndexPath = self.indexPathForRowAtPoint(touch1.locationInView(self))
guard (oldIndexPath != nil) else{
return
}
let oldCell = self.cellForRowAtIndexPath(self.oldIndexPath!)
customView = UIImageView(frame: CGRectMake(0, touch1.locationInView(self).y - 20, self.frame.width, 40))
customView?.image = screenShotView(oldCell!)
customView?.layer.shadowColor = UIColor.blackColor().CGColor
customView?.layer.shadowOpacity = 0.5
customView?.layer.shadowOffset = CGSizeMake(1, 1)
self.addSubview(customView!)
oldCell?.alpha = 0
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
guard let touch1 = touches.first else{
return
}
let newIndexPath = self.indexPathForRowAtPoint(touch1.locationInView(self))
guard newIndexPath != nil else{
return
}
guard oldIndexPath != nil else{
return
}
if newIndexPath != oldIndexPath{
self.moveRowAtIndexPath(oldIndexPath!, toIndexPath: newIndexPath!)
oldIndexPath = newIndexPath
self.cellForRowAtIndexPath(self.oldIndexPath!)!.alpha = 0
}
self.customView!.frame.origin = CGPointMake(0, touch1.locationInView(self).y - 20)
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
self.customView?.removeFromSuperview()
self.customView = nil
guard (oldIndexPath != nil) else{
return
}
self.cellForRowAtIndexPath(self.oldIndexPath!)!.alpha = 1
}
func screenShotView(view: UIView) -> UIImage? {
let rect = view.bounds
UIGraphicsBeginImageContextWithOptions(rect.size,true,0.0)
let context = UIGraphicsGetCurrentContext()
CGContextTranslateCTM(context, 0, -view.frame.origin.y);
self.layer.renderInContext(context!)
let capturedImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return capturedImage
}
}
В конце концов, вы можете изменить порядок ячеек без использования ручек.Это может быть расширено для разных жестов или режимов в зависимости от варианта использования, но я оставил это как ванильную версию.Дайте знать, если у вас появятся вопросы.
Обновление:
Некоторые замечания, которые я нашел.Очень важно, чтобы вы выяснили, как вы хотите использовать прокрутку, и измените ее соответствующим образом.Например, когда я его смоделировал, я установил scrollingEnabled = false.
. В долгосрочной перспективе мне захотелось прокручивать, поэтому я изменил код, чтобы запускать эту функцию только при печати длиннее 0,25 (для этого я использовал некоторые таймеры).Затем я временно отключил бы прокрутку в течение этого периода и снова включил бы ее по завершении.