UITableView deleterows 滚动到顶部

Posted

技术标签:

【中文标题】UITableView deleterows 滚动到顶部【英文标题】:UITableView deleterows scroll to top 【发布时间】:2017-01-06 09:11:04 【问题描述】:

我进行了查询以删除 UITableView 中的指定行,但是当 deleteRows 被称为 UITableView 滚动到顶部时出现问题,那么如何防止它滚动到顶部?以及为什么它会滚动到顶部!

我尝试调用一个方法来强制它向下滚动,但返回后 tableview 首先滚动到顶部 删除代码

FIRDatabase.database().reference().child("messages").child(self.roomId).observe(.childRemoved, with: (snap) in
        print("child Removed")
        for msg in self.messageArray 
            let message: NSDictionary = msg as! NSDictionary
            let messageContent: [String: Any] = message as! [String: Any]
            if messageContent["messageID"] as! String == snap.key 
                let indexRemoved = self.messageArray.index(of: msg)
                self.messageArray.remove(msg)
                self.userArray.removeObject(at: indexRemoved)
                let indexPath = IndexPath(row: indexRemoved, section: 0)
                print(indexPath)
                self.conversationTableView.deleteRows(at: [indexPath], with: UITableViewRowAnimation.none)
                break;
               
        
        )

【问题讨论】:

可能不是您想要的,但您不应该在每个循环范围内都执行删除行。在闭包的第一行创建数组,并添加删除的索引路径。循环结束后,删除添加的数组。 有什么区别?除了我的问题是滚动的变化而不是删除本身 我在源码中没有发现任何与滚动相关的问题。我怀疑有任何逻辑可以在 cellForRowAt indexPath 或其他地方更新整个表格来设置单元格。拥有完整的代码意味着其他人可以找出确切的原因。没错。这不是原因,但是UITableView在循环中一一运行deleteRows并不是好代码。 deleteRows 函数可以接收数组。 【参考方案1】:

请确保您没有使用“estimatedHeightFor...”之类的表格视图方法来计算删除行后滚动表格视图的高度。要确定的另一点是,如果您不想滚动表格,则在从表格视图中删除行时不应使用 reloadData 方法。

如果一切正常,那么在删除特定行时,表格视图会将所有行向上移动以填充已删除行的空白空间。

【讨论】:

我同时使用estimatedHeightForRowAt和heightForRowAt来使单元格自动调整大小,如果删除时出现问题,那么如何防止tableview在删除后调用它们?以及reloadData的另一点我在删除后没有调用它 可以使用 heightForRowAt 但estimatedHeightForRowAt 会使表格视图自动滚动到顶部。实际上,为什么它会发生我不知道,但现在,我只能说,请尝试不使用估计的HeightForRowAt,然后请让我知道输出是什么?【参考方案2】:

代码中存在一些可以轻松纠正的问题。

在做任何事情之前,首先获取第一个可见项目的当前滚动位置(假设单元格大小相同)

let savedIndex = myTableView.indexPathsForVisibleRows?.first

然后,一旦从数组中删除该行并重新加载 tableview,就可以返回到原来的位置

myTableView.scrollToRowAtIndexPath(savedIndex, atScrollPosition: .Top, animated: false)

如果您需要其他选项(可变高度),您可以使用

tableView.contentOffset.y;

此外,无需遍历整个数组即可找到要从中删除的行。假设 Firebase 节点数据作为一个类存储在数组中,在具有 Firebase 键作为每个类的属性的数组中,您可以简单地获取该元素在数组中的索引并将其删除。这是一个选项

let key = snapshot.key

if let index = self.myArray.indexOf($0.firebaseKey == key) 
     self.myArray.removeAtIndex(index)
     self.myTableView.reloadData()

这个对象看起来像:

class MyClass 
    var firebaseKey: String?
    var some_var: String?
    var another_var: String?

【讨论】:

以上是关于UITableView deleterows 滚动到顶部的主要内容,如果未能解决你的问题,请参考以下文章

如何在 UITableView 中插入和删除行时模拟折纸

UITableView 以级联动画的方式进行行的删除和插入

UITableView 滚动 UINavigationBar

UITableView 滚动不滚动

为啥滚动 UITableView 比滚动 UIScrollView 响应更快?

使用 UITableView 在 UITableView 上自动滚动 UIImageView