Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/120.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 UITableView以级联动画方式执行行删除和插入_Ios_Swift_Uitableview_Uiviewanimation - Fatal编程技术网

Ios UITableView以级联动画方式执行行删除和插入

Ios UITableView以级联动画方式执行行删除和插入,ios,swift,uitableview,uiviewanimation,Ios,Swift,Uitableview,Uiviewanimation,我感兴趣的是使用动画tableView.deleteRows(位于:[singleIndexPath],带:。automatic)从UITableView中删除一批行。但是,我的目标是层叠删除动画,以便它们以层叠动画的方式发生,这样,动画将一个接一个地显示删除的行,而不是删除整批行 我发现了一个有用的UITableView扩展,在那里我可以在动画完成后获得一个完成块,例如: extension UITableView { /// Perform a series of method c

我感兴趣的是使用动画
tableView.deleteRows(位于:[singleIndexPath],带:。automatic)
UITableView
中删除一批行。但是,我的目标是层叠删除动画,以便它们以层叠动画的方式发生,这样,动画将一个接一个地显示删除的行,而不是删除整批行

我发现了一个有用的
UITableView
扩展,在那里我可以在动画完成后获得一个完成块,例如:

extension UITableView {

    /// Perform a series of method calls that insert, delete, or select rows and sections of the table view.
    /// This is equivalent to a beginUpdates() / endUpdates() sequence,
    /// with a completion closure when the animation is finished.
    /// Parameter update: the update operation to perform on the tableView.
    /// Parameter completion: the completion closure to be executed when the animation is completed.

    func performUpdate(_ update: ()->Void, completion: (()->Void)?) {

        CATransaction.begin()
        CATransaction.setCompletionBlock(completion)

        // Table View update on row / section
        beginUpdates()
        update()
        endUpdates()

        CATransaction.commit()
    }

}
我的问题是如何利用块自动执行行删除(以及稍后的行插入)的动画。现在,下面的示例代码有两行
indepath
s,仍然有动画同时出现,这不是我的目标

    let singleIndexPath = IndexPath(row: 0, section: 0)
    let anotherIndexPath = IndexPath(row: 1, section: 0)

    self.tableView.performUpdate({

        self.tableView.deleteRows(at: [singleIndexPath, anotherIndexPath], with: .automatic)
        self.tableView.insertRows(at: [singleIndexPath, anotherIndexPath], with: .left)
        //Happening at the same time, which is not what I want
    }, completion: {

    })

非常感谢任何提示。

级联表视图行删除

用法:

let indexPathsToDelete = [IndexPath(row: 1, section: 0), IndexPath(row: 4, section: 0), IndexPath(row: 6, section: 0)]
 deleteRowsAt(indexPaths: indexPathsToDelete, in: tableView)
func deleteRowsAt(indexPaths: [IndexPath], in tableView: UITableView) {
    var state = (0 ..< tableView.numberOfSections).map {
        Array(0 ..< tableView.numberOfRows(inSection: $0))
    }

    func cascadeDeleteAt(indexPath indexPathToDelete: IndexPath) {

        // Get the current row for the index path we wish to delete.
        // It could be diffrent to its original index path if other rows have been deleted.
        guard let currentRow = state[indexPathToDelete.section].index(of: indexPathToDelete.row) else { return }

        let currentIndexPath = IndexPath(row: currentRow, section: indexPathToDelete.section)
        print(currentIndexPath)

        // --- IMPLEMENT THE DELETION FROM YOUR DATA SOURCE ---
        source.remove(at: currentIndexPath.row)


        state[indexPathToDelete.section].remove(at: currentIndexPath.row)

        tableView.performUpdate({
            tableView.deleteRows(at: [currentIndexPath], with: .left)
        }, completion: {
            guard var idx = indexPaths.index(of: indexPathToDelete) else { return }
            idx += 1
            if idx < indexPaths.count {
                let nextIndexPathToDelete = indexPaths[idx]
                cascadeDeleteAt(indexPath: nextIndexPathToDelete)
            }
        })
    }

    if let indexPath = indexPaths.first {
        cascadeDeleteAt(indexPath: indexPath)
    }
}
代码:

let indexPathsToDelete = [IndexPath(row: 1, section: 0), IndexPath(row: 4, section: 0), IndexPath(row: 6, section: 0)]
 deleteRowsAt(indexPaths: indexPathsToDelete, in: tableView)
func deleteRowsAt(indexPaths: [IndexPath], in tableView: UITableView) {
    var state = (0 ..< tableView.numberOfSections).map {
        Array(0 ..< tableView.numberOfRows(inSection: $0))
    }

    func cascadeDeleteAt(indexPath indexPathToDelete: IndexPath) {

        // Get the current row for the index path we wish to delete.
        // It could be diffrent to its original index path if other rows have been deleted.
        guard let currentRow = state[indexPathToDelete.section].index(of: indexPathToDelete.row) else { return }

        let currentIndexPath = IndexPath(row: currentRow, section: indexPathToDelete.section)
        print(currentIndexPath)

        // --- IMPLEMENT THE DELETION FROM YOUR DATA SOURCE ---
        source.remove(at: currentIndexPath.row)


        state[indexPathToDelete.section].remove(at: currentIndexPath.row)

        tableView.performUpdate({
            tableView.deleteRows(at: [currentIndexPath], with: .left)
        }, completion: {
            guard var idx = indexPaths.index(of: indexPathToDelete) else { return }
            idx += 1
            if idx < indexPaths.count {
                let nextIndexPathToDelete = indexPaths[idx]
                cascadeDeleteAt(indexPath: nextIndexPathToDelete)
            }
        })
    }

    if let indexPath = indexPaths.first {
        cascadeDeleteAt(indexPath: indexPath)
    }
}
func deleteRowsAt(表视图中的IndexPath:[IndexPath]:UITableView){
变量状态=(0..
以级联方式删除行(即一次删除一行而不是一次删除所有行)时,棘手的部分是:

  • 删除一行后,其他索引(索引路径和数据源中的索引)不会指向它们以前所在的位置
  • 需要从递归函数中调用函数
    performUpdate
    ,以便仅在删除当前行后才能删除下一行

  • 您是否需要将要删除的每个索引路径放在单独调用
    performUpdate
    的更新处理程序中?@paulvs是的,但这不会自动执行,也不会基于我拥有的行数。我可以对行进行硬编码,但这将是无效的。这真是太棒了。我试图找到一个递归解决方案,但遇到了您提到的问题,IndExpath没有指向它们过去的位置。你设法优雅地解决了这个问题。非常感谢。