Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ember.js/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如何在使用UITableViewDiffableDataSource时移动UITableView单元格?_Ios_Swift_Uitableview_Uikit - Fatal编程技术网

Ios 如何在使用UITableViewDiffableDataSource时移动UITableView单元格?

Ios 如何在使用UITableViewDiffableDataSource时移动UITableView单元格?,ios,swift,uitableview,uikit,Ios,Swift,Uitableview,Uikit,我试图使我的tableView单元格可移动,但它需要来自uitableview数据源协议的2或3个函数,如果我试图在我的viewController中实现委托,它将要求numberOfRowsInSection和cellforrowatinexpath函数,这些函数已经包含在新的UITableViewDiffableDataSource中 如何在使用新的UITableViewDiffableDataSource时实现此行为?我可以通过如下子类化UITableViewDiffableDataSou

我试图使我的
tableView单元格
可移动,但它需要来自
uitableview数据源
协议的2或3个函数,如果我试图在我的
viewController
中实现委托,它将要求
numberOfRowsInSection
cellforrowatinexpath
函数,这些函数已经包含在新的
UITableViewDiffableDataSource


如何在使用新的
UITableViewDiffableDataSource
时实现此行为?

我可以通过如下子类化
UITableViewDiffableDataSource
类来实现这一点:

类MyDataSource:UITableViewDiffableDataSource{
重写func tableView(tableView:UITableView,moveRowAt sourceIndexPath:IndexPath,to destinationIndexPath:IndexPath){
//更新真相来源的代码
//从你的真相来源拍一张新的快照
//应用(快照、动画差异:false)
}
}
然后,您可以覆盖实现所需的任何数据源方法。

为了充实您的答案,下面是一个完整的实现:

class MovableTableViewDataSource: UITableViewDiffableDataSource<Int, Int> {

    override func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
        super.tableView(tableView, moveRowAt: sourceIndexPath, to: destinationIndexPath)

        var snapshot = self.snapshot()
        if let sourceId = itemIdentifier(for: sourceIndexPath) {
            if let destinationId = itemIdentifier(for: destinationIndexPath) {
                guard sourceId != destinationId else {
                    return // destination is same as source, no move.
                }
                // valid source and destination
                if sourceIndexPath.row > destinationIndexPath.row {
                    snapshot.moveItem(sourceId, beforeItem: destinationId)
                } else {
                    snapshot.moveItem(sourceId, afterItem: destinationId)
                }
            } else {
                // no valid destination, eg. moving to the last row of a section
                snapshot.deleteItems([sourceId])
                snapshot.appendItems([sourceId], toSection: snapshot.sectionIdentifiers[destinationIndexPath.section])
            }
        }

        apply(snapshot, animatingDifferences: false, completion: nil)
    }
}
类MovableTableViewDataSource:UITableViewDiffableDataSource{
重写func tableView(tableView:UITableView,moveRowAt sourceIndexPath:IndexPath,to destinationIndexPath:IndexPath){
tableView(tableView,moveRowAt:sourceindepath,to:destinationindepath)
var snapshot=self.snapshot()
如果让sourceId=itemIdentifier(for:sourceIndexPath){
如果让destinationId=itemIdentifier(for:destinationIndexPath){
guard sourceId!=destinationId else{
return//目标与源相同,不移动。
}
//有效的源和目标
如果sourceIndexPath.row>destinationIndexPath.row{
snapshot.moveItem(sourceId,beforeItem:destinationId)
}否则{
snapshot.moveItem(sourceId,afterItem:destinationId)
}
}否则{
//没有有效的目的地,例如移动到区段的最后一行
snapshot.deleteItems([sourceId])
snapshot.appendItems([sourceId],toSection:snapshot.sectionIdentifiers[DestinationIndepath.section])
}
}
应用(快照、动画差异:false、完成:nil)
}
}
如果
animatingDifferences
设置为true,它将崩溃(无论如何,这里不需要设置动画)


我不确定是否需要调用
super.tableView(move…
,但它似乎没有任何危害。

不幸的是,moveRow和canMove是UITableViewDataSource方法。。。您有关于此功能的一些消息吗?这个答案似乎有一个问题:“if sourceIndexPath.row>destinationIndexPath.row”假设源和目标都在同一节中,这可能不是真的。每个部分都有自己的0…n行编号。注意:编辑此(优秀)答案,以包括在决定快照位置时注意源/目标部分的附加逻辑。moveItem()。如果它适用于任何人,我还将指出:如果将“真实来源”模型数据保留在TableView外部,仅从表视图更改快照并不同时更新模型数据。这是你必须自己做的另一件事。有趣的是,这在iOS 14(Xcode 12.2)上不起作用。需要其他设置吗?例如
tableView.isEditing=true
?@通配符,是的,UITableView需要处于编辑模式才能进行单元格重新排序,
isEditing=true
。您可能还需要将单元格的编辑模式设置为
.none
,我记得这是在
tableView:cellforrowatinexpath:
委托方法中完成的。