在我的项目中,我想要实现移动行以及删除它们但不使用库存“删除”按钮,而是通过点击我的自定义 UITableViewCell 中的图像 QueueCell 。我删除函数 deleteByTap2 中的行,它使用 sender.tag ( cell.indexPath.row )来识别应删除哪个单元格。移动和删除工作都很好,但是当你移动时,例如,第6行到第2行它仍然带有tag = 6,因此当我点击图像删除行时,错误的行被删除。我创建了一个函数 reTag ,它应该更新各个部分中的所有单元格的标签,并且在 deleteByTap2 函数中调用后效果很好但是在结束时调用
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath)
它似乎不知道移动行后tableView的状态。我搜索了论坛,发现有无证件 UITableViewDelegate 功能
- (void)tableView:(UITableView *)tableView didEndReorderingRowAtIndexPath:(NSIndexPath *)indexPath;
但我尝试调用它,它似乎已被删除(或者名称已更改) 我什么时候应该调用 reTag 功能才能正常工作?那么在重新排序后它会知道tableView的顺序吗?
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! QueueCell
let item = sungs[indexPath.section].songsIn[indexPath.row]
cell.setup(item: item)
if indexPath.section == 2{
let tap = UITapGestureRecognizer(target: self, action: #selector(deleteByTap2(_:)))
tap.numberOfTapsRequired = 1
tap.numberOfTouchesRequired = 1
cell.artwork.addGestureRecognizer(tap)
cell.artwork.isUserInteractionEnabled = true
cell.artwork.tag = indexPath.row
}
return cell
}
override func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
var toMove: MPMediaItem
tableView.beginUpdates()
if sourceIndexPath.section == 2{
if player.isShuffle{
toMove = player.shufQueue[player.shufIndex + sourceIndexPath.row + 1]
player.shufQueue.remove(at: player.shufIndex + sourceIndexPath.row + 1)
if destinationIndexPath.section == 2{
player.shufQueue.insert(toMove, at: player.shufIndex + destinationIndexPath.row + 1)
}
}else{
toMove = player.defQueue[player.defIndex + sourceIndexPath.row + 1]
player.defQueue.remove(at: player.defIndex + sourceIndexPath.row + 1)
if destinationIndexPath.section == 2{
player.defQueue.insert(toMove, at: player.defIndex + destinationIndexPath.row + 1)
}
}
}
tableView.endUpdates()
reTag(section: destinationIndexPath.section)
}
//the beginUpdates()-endUpdates() doesn't do much good here, actually it messes some of my cells
func reTag(section: Int){
var indexPath: IndexPath
for row in 0 ..< tableView.numberOfRows(inSection: section){
indexPath = IndexPath(row: row, section: section)
if let cell = tableView.cellForRow(at: indexPath) as? QueueCell{
cell.artwork.tag = row
}
}
}
func deleteByTap2(_ sender: UITapGestureRecognizer){
let tag = (sender.view?.tag)!
if player.isUsrQueue{
player.usrQueue.remove(at: player.usrIndex + tag + 1)
player.usrQueueCount! -= 1
sungs[2].songsIn.remove(at: tag)
}else{
player.defQueue.remove(at: player.defIndex + tag + 1)
sungs[2].songsIn.remove(at: tag)
player.defQueueCount! -= 1
}
let indexPath = IndexPath(row: tag, section: 2)
tableView.deleteRows(at: [indexPath], with: .fade)
reTag(section: 2)
}
答案 0 :(得分:1)
这是一个很好的例子,说明为什么在对象上使用.tag
来尝试以这种方式跟踪它们是个坏主意。
我建议您在单元格类中移动点击手势,然后添加&#34;回拨&#34;关闭。当然,此示例缺少您的数据类和cell.setup()
代码,但您应该能够看到需要更改的内容:
// cell class
class QueueCell: UITableViewCell {
@IBOutlet weak var artwork: UIImageView!
var tapCallback: ((QueueCell) -> ())?
func addTap() {
if artwork.gestureRecognizers == nil {
// cells are reused, so only add this once
let tap = UITapGestureRecognizer(target: self, action: #selector(artworkTap(_:)))
tap.numberOfTapsRequired = 1
tap.numberOfTouchesRequired = 1
artwork.addGestureRecognizer(tap)
artwork.isUserInteractionEnabled = true
}
}
func artworkTap(_ sender: UITapGestureRecognizer) -> Void {
tapCallback?(self)
}
}
// table view class
override func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
// all you have to do is manage your data,
// no need to reload() or "re-tag" anything
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "QueueCell", for: indexPath) as! QueueCell
// your cell configuration
//let item = sungs[indexPath.section].songsIn[indexPath.row]
//cell.setup(item: item)
if indexPath.section == 2 {
// tell the cell to add the gesture recognizer
cell.addTap()
// set the "call back" closure
cell.tapCallback = {
theCell in
if let iPath = tableView.indexPath(for: theCell) {
self.deleteByTap2(tableView, indexPath: iPath)
}
}
}
return cell
}
func deleteByTap2(_ tableView: UITableView, indexPath: IndexPath) -> Void {
print("Tapped on artwork at:", indexPath)
// you now have a reference to the table view and the indexPath for the cell that
// contained the artwork image view that was tapped
}
现在,您的deleteByTap2()
功能将与熟悉的didSelectRowAt
功能相匹配,您可以在那里处理删除。