最新消息:20210917 已从crifan.com换到crifan.org

[已解决]swift中tableView.moveRowAtIndexPath不工作:没有及时响应

Swift crifan 2245浏览 0评论

使用代码:

                   print("before move cell:")
                    for (curIdx, eachConversationItem) in self.conversationItemList.enumerate(){
                        print("[\(curIdx)] \(eachConversationItem.msgTVC.contactItem.name),\(eachConversationItem.descDetailStr),\(eachConversationItem.descAtMeStr),\(eachConversationItem.lastPublishDatetimeStr)")
                    }
                   
                    //move this cell to top
                    let newIndexPath:NSIndexPath = NSIndexPath(forRow: 0, inSection: 0)
                    print("from [\(curIndexPath.row)] to \(newIndexPath.row)")
                    self.tableView.moveRowAtIndexPath(curIndexPath, toIndexPath: newIndexPath)
                    print("after  move cell:")
                    for (curIdx, eachConversationItem) in self.conversationItemList.enumerate(){
                        print("[\(curIdx)] \(eachConversationItem.msgTVC.contactItem.name),\(eachConversationItem.descDetailStr),\(eachConversationItem.descAtMeStr),\(eachConversationItem.lastPublishDatetimeStr)")
                    }

输出是:

before move cell:
[0] 简道前端开发,啦啦啦啦啦啦啦噜噜,,09:45:14
[1] 简道开发,,,
[2] All,大家好 我是王佳慧,,10:45:23
[3] 简道公告,,,
[4] 三人行,,,
from [2] to 0
after  move cell:
[0] 简道前端开发,啦啦啦啦啦啦啦噜噜,,09:45:14
[1] 简道开发,,,
[2] All,你好 ,,11:04:22
[3] 简道公告,,,
[4] 三人行,,,

很明显:

经过self.tableView.moveRowAtIndexPath结果没有正常工作:

没有及时的从2切换到0

搜:

swift moveRowAtIndexPath not work

UITableViewDataSource Protocol Reference

Swift – Reorder UITableView cells – Stack Overflow

-》

TableViewOperationInSwift/ViewController.swift at master · suryakants/TableViewOperationInSwift · GitHub

好像是:

需要自己去实现对应的:

moveRowAtIndexPath

的。。。

UITableViewController rearrange or reorder table cells example in Swift – Swift Developer Blog

UITableView: Deleting, Moving, and Viewing Rows

swift uitableview move cell

swift 列表 移动单元格

Reordering Rows from Table View in iOS8 with Swift – iOScreator

Swift – 给表格添加移动单元格功能(拖动行)

实现了moveRowAtIndexPath:

    func tableView(tableView: UITableView, moveRowAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath){
        print("ConversationViewController moveRowAtIndexPath: from \(sourceIndexPath) to \(destinationIndexPath)")
        let sourceConversationItem = self.conversationItemList.removeAtIndex(sourceIndexPath.row)
        self.conversationItemList.insert(sourceConversationItem, atIndex: destinationIndexPath.row)
    }

结果:

问题依旧。。。

swift-高级UI之UITableView移动单元格(十三)_IOS编程网

去试试,添加canMoveRowAtIndexPath

    func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
        return true
    }

结果也都没有被调用到:

问题依旧。

QuickRearrangeTableView/ViewController.swift at master · okla/QuickRearrangeTableView · GitHub

搜:

swift tableview cell move programmatically

直接使用ViewController的实例变量去更新:

self.tableView.moveRowAtIndexPath(curIndexPath, toIndexPath: newIndexPath)
//                    gConversationTVC.tableView.moveRowAtIndexPath(curIndexPath, toIndexPath: newIndexPath)

也没用。

添加了:beginUpdates和endUpdates:

                    //move this cell to top
                    self.tableView.beginUpdates()
                    let newIndexPath:NSIndexPath = NSIndexPath(forRow: 0, inSection: 0)
                    print("from [\(curIndexPath.row)] to \(newIndexPath.row)")
                    print("self=\(self), gConversationTVC=\(gConversationTVC)")
                    self.tableView.moveRowAtIndexPath(curIndexPath, toIndexPath: newIndexPath)
                    self.tableView.endUpdates()

也是没用:

搜:

moveRowAtIndexPath not call

swift moveRowAtIndexPath not call

swift uitableview move cell

UITableView Moves and Updates | Matrix Projects .Net

move完毕再去reloadRowsAtIndexPaths:

                    self.tableView.reloadRowsAtIndexPaths([curIndexPath, newIndexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
//                    self.tableView.reloadRowsAtIndexPaths([curIndexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
//                    self.tableView.reloadRowsAtIndexPaths([newIndexPath], withRowAnimation: UITableViewRowAnimation.Automatic)

也没用。。。

UITableView Moves and Updates | Matrix Projects .Net

搜:

moverowatindexpath not called

ios – Call moveRowAtIndexPath from TableViewController – Stack Overflow

找到原因了:

“Moving (or adding, removing) table view rows by code (and not by user interaction) does not cause the data source methods to be called.”

搜:

call moveRowAtIndexPath by code

objective c – How to call pickerView: didSelectRow: inComponent: without user interaction? – Stack Overflow

结果不论是:

                    self.tableView.moveRowAtIndexPath(curIndexPath, toIndexPath: newIndexPath)
                    self.tableView(self.tableView, moveRowAtIndexPath: curIndexPath, toIndexPath: newIndexPath)

还是:

                    self.tableView(self.tableView, moveRowAtIndexPath: curIndexPath, toIndexPath: newIndexPath)

虽然调用到了对应的moveRowAtIndexPath,但是问题依旧:

移动后的单元格,全部错乱了:

原来是刚才搞错了:

原来是:

tableView.moveRowAtIndexPath

tableView(self.tableView, moveRowAtIndexPath

之后再去:

self.tableView.reloadRowsAtIndexPaths

                    self.tableView.moveRowAtIndexPath(curIndexPath, toIndexPath: newIndexPath)
                    self.tableView(self.tableView, moveRowAtIndexPath: curIndexPath, toIndexPath: newIndexPath)
                   
                   
                    self.tableView.reloadRowsAtIndexPaths([curIndexPath, newIndexPath], withRowAnimation: UITableViewRowAnimation.Automatic)

而导致的上述单元格内容都错乱了。

而且,也去试了试:

只调用:

self.tableView(self.tableView, moveRowAtIndexPath: curIndexPath, toIndexPath: newIndexPath)

也还是会错乱的:

而只用:

                    //move this cell to top
                    let newIndexPath:NSIndexPath = NSIndexPath(forRow: 0, inSection: 0)
                    print("from [\(curIndexPath.row)] to \(newIndexPath.row)")
                    self.tableView.moveRowAtIndexPath(curIndexPath, toIndexPath: newIndexPath)
                   self.tableView(self.tableView, moveRowAtIndexPath: curIndexPath, toIndexPath: newIndexPath)

其中不需要:

beginUpdates和endUpdates

就可以正常,用纯代码(而不是用户在界面中手动操作)的方式,去移动单元格了:

然后就可以实现:

新行,插入到顶部:

已有的行,更新内容后,移动到顶部:

[总结]

此处通过tableView去调用moveRowAtIndexPath而没有反应,moveRowAtIndexPath 不工作的原因是:

iOS设计了这些函数,包括但不限于:

moveRowAtIndexPath

didSelectRowAtIndexPath

都是希望用户在界面(即,用户在iOS设备上,用手指点击或移动等)操作,才会被调用

-》而直接在代码中去调用之类函数:

self.tableView.moveRowAtIndexPath(curIndexPath, toIndexPath: newIndexPath)

内部代码执行时,是不会调用对应的:

(你的tableView的delegate的

    func tableView(tableView: UITableView, moveRowAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath){
        print("moveRowAtIndexPath: from \(sourceIndexPath) to \(destinationIndexPath)")
       
        let sourceConversationItem = self.conversationItemList.removeAtIndex(sourceIndexPath.row)
        self.conversationItemList.insert(sourceConversationItem, atIndex: destinationIndexPath.row)
    }

-》所以此处自己去额外手动的调用:

let newIndexPath:NSIndexPath = NSIndexPath(forRow: 0, inSection: 0)
print("from [\(curIndexPath.row)] to \(newIndexPath.row)")
self.tableView.moveRowAtIndexPath(curIndexPath, toIndexPath: newIndexPath)
self.tableView(self.tableView, moveRowAtIndexPath: curIndexPath, toIndexPath: newIndexPath)

就可以正常实现:

某行数据被更新后,通过moveRowAtIndexPath而把该行移动到(row=0)顶部。

-》

iOS的这点设计,真够坑的。

最最主要的是:

网上搜了这么半天,竟然很少有人提及。。。

-》

及时不支持代码中调用,那么官网中:

https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableViewDataSource_Protocol/#//apple_ref/occ/intfm/UITableViewDataSource/tableView:moveRowAtIndexPath:toIndexPath:

至少也该要多写点说明和注释啊。。。

转载请注明:在路上 » [已解决]swift中tableView.moveRowAtIndexPath不工作:没有及时响应

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

网友最新评论 (1)

  1. your article is nice here tutorial is https://www.welookups.com
    aditya6年前 (2018-07-09)回复
97 queries in 0.209 seconds, using 23.52MB memory