使用UIGestureRecognizer对TableView单元格重新排序
最近,我有幸与一家创业公司的创始人通过咖啡见面,其中一位创始人提到了iPhone上的Weather应用程序。 具体来说,他提到了如何在应用程序中,用户可以重新排序他们对城市的偏好。 外观如下:
尽管这是一个小功能,但我知道这是我可以解决并进一步研究的东西,因为它真的使我对如何编写代码感兴趣。 有几种方法可以在项目中实现这一目标。 我发现了两种不同的方式,我将同时提及两种方式,但仅介绍我的首选方式。
第一种方法是更简便,更快捷的方法。 用户只需要首先运行一个简单的表视图并添加示例数据即可显示。 接下来,在情节提要中或以编程方式添加一个条形按钮项。 实现startEditing方法,然后取消注释canMoveRowAtIndexPath和moveRowAtIndexPath方法。 前者应返回true,而后者应用于对样本数组中的项目重新排序。
第二种方法是我更喜欢的方法,因为您无需实现编辑,并且可以在运行程序后立即重新排列表视图的顺序。 它涉及更多代码,但我认为这是值得的。
这是我采取的步骤。 我很幸运地在线找到了方法论(请参阅此处),并将其转换为Swift 3。
在您的tableview的viewDidLoad中,添加以下代码:
let longpress = UILongPressGestureRecognizer(目标:自我,行动:#selector(TableViewController.longPressGestureRecognized(_ :)))
tableView.addGestureRecognizer(longpress)
接下来创建您的longPressGestureRecognized函数:
func longPressGestureRecognized(_手势识别器:UIGestureRecognizer){
}
在此函数内添加以下代码:
让longPress = gestureRecognizer为! UILongPressGestureRecognizer
让状态= longPress.state
让locationInView = longPress.location(in:tableView)
让indexPath = tableView.indexPathForRow(at:locationInView)
struct My {
静态var cellSnapshot:UIView吗? =无
静态var cellIsAnimating:Bool = false
静态var cellNeedToShow:Bool = false
}
结构路径{
静态var initialIndexPath:IndexPath吗? =无
}
切换状态{
案例UIGestureRecognizerState.began:
如果indexPath!= nil {
Path.initialIndexPath = indexPath
让cell = tableView.cellForRow(at:indexPath!)作为UITableViewCell!
My.cellSnapshot = snapshotOfCell(单元格!)
var center = cell?.center
My.cellSnapshot!.center =中心!
My.cellSnapshot!.alpha = 0.0
tableView.addSubview(My.cellSnapshot!)
UIView.animate(withDuration:0.25,animations:{()-> Void in
中心?.y = locationInView.y
My.cellIsAnimating = true
My.cellSnapshot!.center =中心!
My.cellSnapshot!.transform = CGAffineTransform(scaleX:1.05,y:1.05)
My.cellSnapshot!.alpha = 0.98
cell?.alpha = 0.0
},完成:{(完成)->无效
如果完成{
My.cellIsAnimating = false
如果My.cellNeedToShow {
My.cellNeedToShow = false
UIView.animate(withDuration:0.25,animations:{()-> Void in
cell?.alpha = 1
})
}其他{
cell?.isHidden = true
}
}
})
}
案例UIGestureRecognizerState.changed:
如果My.cellSnapshot!= nil {
var center = My.cellSnapshot!.center
center.y = locationInView.y
My.cellSnapshot!.center =中心
如果((indexPath!= nil)&&(indexPath!= Path.initialIndexPath)){
itemsArray.insert(itemsArray.remove(at:Path.initialIndexPath!.row),at:indexPath!.row)
tableView.moveRow(at:Path.initialIndexPath !, to:indexPath!)
Path.initialIndexPath = indexPath
}
}
默认:
如果Path.initialIndexPath!= nil {
让cell = tableView.cellForRow(at:Path.initialIndexPath!)作为UITableViewCell!
如果My.cellIsAnimating {
My.cellNeedToShow = true
}其他{
cell?.isHidden = false
cell?.alpha = 0.0
}
UIView.animate(withDuration:0.25,animations:{()-> Void in
My.cellSnapshot!.center =(cell?.center)!
My.cellSnapshot!.transform = CGAffineTransform.identity
My.cellSnapshot!.alpha = 0.0
cell?.alpha = 1.0
},完成:{(完成)->无效
如果完成{
Path.initialIndexPath =无
My.cellSnapshot!.removeFromSuperview()
My.cellSnapshot =无
}
})
}
}
接下来在下面添加snapshotOfCell函数
func snapshotOfCell(_ inputView:UIView)-> UIView {
UIGraphicsBeginImageContextWithOptions(inputView.bounds.size,false,0.0)
inputView.layer.render(in:UIGraphicsGetCurrentContext()!)
让图像= UIGraphicsGetImageFromCurrentImageContext()! 作为UIImage
UIGraphicsEndImageContext()
让cellSnapshot:UIView = UIImageView(image:图片)
cellSnapshot.layer.masksToBounds = false
cellSnapshot.layer.cornerRadius = 0.0
cellSnapshot.layer.shadowOffset = CGSize(宽度:-5.0,高度:0.0
cellSnapshot.layer.shadowRadius = 5.0
cellSnapshot.layer.shadowOpacity = 0.4
返回cellSnapshot
}
最后,请确保实现通常被注释掉的tableview方法。
覆盖func tableView(_ tableView:UITableView,numberOfRowsInSection部分:Int)-> Int {
返回itemsArray.count
}
覆盖func tableView(_ tableView:UITableView,cellForRowAt indexPath:IndexPath)-> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier:“ Cell”,for:indexPath)作为UITableViewCell
cell.textLabel?.text = itemsArray [indexPath.row]
cell.textLabel?.textColor? = UIColor.white
返回单元
}
覆盖func tableView(_ tableView:UITableView,didSelectRowAt indexPath:IndexPath){
tableView.deselectRow(at:indexPath,animation:false)
}
如果您有NBA篮球队的名单,将会是这样。