Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.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将单元格放置在tableview页脚时移动到最后一行_Ios_Swift_Uitableview - Fatal编程技术网

Ios UITableView将单元格放置在tableview页脚时移动到最后一行

Ios UITableView将单元格放置在tableview页脚时移动到最后一行,ios,swift,uitableview,Ios,Swift,Uitableview,在iOS 11中,我们有了新的拖放API,它使用现有的UITableViewDelegate方法对同一tableview中的单行重新排序。我使用空视图作为tableView.tableFooterView,以便将单元格分隔符隐藏在最后一个实际单元格的下方。但是,如果只有几个单元格,并且显示了页脚,那么在尝试将单元格移动到结束位置时可能会很尴尬,因为tableview页脚不接受拖放 有什么方法可以使用吗 func tableView(_ tableView: UITableView, target

在iOS 11中,我们有了新的拖放API,它使用现有的
UITableViewDelegate
方法对同一tableview中的单行重新排序。我使用空视图作为
tableView.tableFooterView
,以便将单元格分隔符隐藏在最后一个实际单元格的下方。但是,如果只有几个单元格,并且显示了页脚,那么在尝试将单元格移动到结束位置时可能会很尴尬,因为tableview页脚不接受拖放

有什么方法可以使用吗

func tableView(_ tableView: UITableView, targetIndexPathForMoveFromRowAt sourceIndexPath: IndexPath, toProposedIndexPath proposedDestinationIndexPath: IndexPath) -> IndexPath
或者使用
UITableViewDropDelegate
中的另一种方法将拖放从tableview页脚重定向到最后一个
indepath


我能想到的唯一其他选择是将页脚设置为自定义放置目标,但这将调整放置预览的大小并更改处理放置的代码路径。

我最终将表视图页脚设置为自定义放置目标。事实证明,拖动的单元格在离开完整表视图的边界之前不会调整大小,因此这是一个非常平滑的解决方案。唯一显著的区别是,使用这种方法,单元格将从其原始索引开始设置动画,而不是从最后一个拖动位置开始放置

编辑根据要求,我找到了我的原始实现,并将其粘贴到下面。除此之外,DND可能还需要一些其他步骤,我不记得了。对于上下文,
ItemsVC
包含一个
UITableView
,其中包含过期、待办事项和已完成事项的3个部分。完成部分可能被用户隐藏,也可能不被用户隐藏。只有在隐藏“完成”部分时,才支持在页脚中删除项目以进行重新排序

// MARK: - Drop in TableView Footer

extension ItemsVC: UIDropInteractionDelegate {

    func dropInteraction(_ interaction: UIDropInteraction, canHandle session: UIDropSession) -> Bool {
        let doneRowCount = tableView.numberOfRows(inSection: PlannerItemGroup.done.rawValue)
        return session.items.count == 1 && doneRowCount == 0
    }

    /**
     Currently this only supports dropping a single SMItem or SMSimulatedItem that is already in the tableview.
     This is inteded to function as an extension of the method:
     func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath)
     */
    func dropInteraction(_ interaction: UIDropInteraction, performDrop session: UIDropSession) {
        guard session.items.count == 1 else {
            return
        }

        let todoItems = viewModel.plannerItems(for: .todo)

        //Cast the localObject as an SMPlannerItem
        guard let plannerItem: SMPlannerItem = session.items.compactMap({ (dragItem: UIDragItem) -> SMPlannerItem? in
            return dragItem.localObject as? SMItem ?? dragItem.localObject as? SMSimulatedItem
        }).first else { return }

        //PlannerItem must come from this tableView and not from the done section
        guard let sourcePath = viewModel.indexPath(for: plannerItem),
            sourcePath.section != PlannerItemGroup.done.rawValue
        else { return }

        let doneRowCount = tableView.numberOfRows(inSection: PlannerItemGroup.done.rawValue)

        if doneRowCount == 0 { //Footer is below todo section
            print("Will move item to end of todo section")

            let destinationPath = IndexPath(item: todoItems.count - 1, section: PlannerItemGroup.todo.rawValue)
            movePlannerItem(plannerItem, from: sourcePath, to: destinationPath, moveRow: true)
        }
    }

    func dropInteraction(_ interaction: UIDropInteraction, sessionDidEnter session: UIDropSession) {
        print("Drop session did enter footer")
    }

    func dropInteraction(_ interaction: UIDropInteraction, sessionDidUpdate session: UIDropSession) -> UIDropProposal {
        return UIDropProposal(operation: .move)
    }

    func dropInteraction(_ interaction: UIDropInteraction, sessionDidExit session: UIDropSession) {
        print("Drop session did exit footer")
    }

    func dropInteraction(_ interaction: UIDropInteraction, sessionDidEnd session: UIDropSession) {
        print("Drop session did end")
    }

}
Swift 5 ios 13.5

最后我做了这个

func tableView(tableView:UITableView,moveRowAt sourceIndexPath:IndexPath,to destinationIndexPath:IndexPath){
//当没有不同的destinationIndexPath时删除动画,这意味着我们在没有单元格的tableview区域上移动
如果sourceIndexPath==destinationIndexPath{
UIView.SetAnimationEnabled(错误)
}
否则{
UIView.SetAnimationEnabled(真)
}
myarray.remove(位于:sourceIndexPath.row)
如果sourceIndexPath!=destinationIndexPath{
插入(todo,位于:destinationIndepath.row)
}
如果sourceIndexPath==destinationIndexPath,则为else{
让therow=myarray.count
myarray.insert(todo,at:therow)
//只是为了在最后一行出现之前增加一点延迟。其他行看起来很难看。
DispatchQueue.main.asyncAfter(截止日期:.now()+0.1){
self.topTableView.reloadData()
}
}
}

将tableView的页脚作为拖放目标,并在回调中将该项添加到数组的末尾,然后重新加载tableView@Sh_Khan是的,我想到了,但我想知道是否有一种方法可以在不收缩单元格(下拉预览)的情况下处理此问题,使其与正常的重新排序UI相匹配。你能举个例子吗?我目前正在尝试对tableview的页脚和“清除”部分执行相同的操作。我已经为tableview实现了拖放功能,但是所有不是直接放在最后一行下面的行都会返回到它们的原始位置。@Nalov您已经为tableview创建了一个自定义页脚视图,您可以使用它的背景色来确认页脚覆盖了您放单元格的区域吗?一旦页脚正常工作,就可以使用调整单元格索引的逻辑为其添加拖放支持。我添加了一个带有标签的uibutton作为tableview页脚。它没有背景。“您可以通过调整单元格索引的逻辑添加对它的drop支持”是什么意思——“这是我遇到困难的部分,您能举一个逻辑的例子吗?”?目前我使用moveRow方法——当它没有得到与SourceIndepath不同的DestinationIndepath时,它将从数组中删除并添加到末尾。它可以工作,但moverow函数动画显示单元格返回到原始位置。我禁用了动画,但现在它只是在结尾出现,没有漂亮的动画。@Nalov我重新阅读了你的问题,听起来你是在问当你把它放在页脚视图中时发生的尴尬动画。根据我在最初回答的最后一句话中所写的内容,恐怕我没有找到解决这个问题的办法。我已经好几年没碰过这个代码了,所以我想我帮不了什么忙。也许SwiftUI会处理得更好。如果你能找到代码,请用你的代码编辑你的答案,因为我也希望看到你的解决方案。