重新加载源数据iOS后,使用动态高度单元格维护UITableView单元格位置

时间:2016-05-27 17:36:54

标签: ios swift uitableview

在聊天应用程序中,我正在chat table view顶部实施加载更多按钮。

当用户点击加载更多按钮时,旧的消息(以及屏幕上显示的所有当前消息)将从DB(使用NSFetchedResultsController)获取,然后我在{{reloadData()上调用chat table view方法1}}。

我想将tableview的滚动位置设置为重新加载表之前的第一行。

根据消息文本,所有消息单元格动态高度

我在故事板上使用auto layout

我的代码:

let oldContentheight = _chatTableView.contentSize.height
_chatTableView.reloadData()
executeOnMain {
    if self.firstTimeFetching {
        self.firstTimeFetching = false
        self.scrollTableToLastRow(withAnimation: false)
        //this is for going to last cell when we come to chat screen
    }
    else {
        //after pressing load more button
        let newContentHeight = self._chatTableView.contentSize.height
        let newOffset = CGPointMake(0, newContentHeight - oldContentheight)
        self._chatTableView.setContentOffset(newOffset, animated: false)
    }
}

2 个答案:

答案 0 :(得分:0)

首先,声明属性以保存顶部可见单元格的索引路径

@property(strong,nonatomic) *topVisibleIndexPath;

然后当您单击加载更多按钮时,您将获得顶部可见单元格IndexPath并保存

NSArray *visibelIndexpaths = [yourTableView.indexPathsForVisibleRows];
if(visibelIndexpaths.count > 0)
    self.topVisibleIndexPath = [visibelIndexpaths firstObject];

重新加载后,您调用方法:

[yourTableView scrollToRowAtIndexPath:self.topVisibleIndexPath atScrollPosition:UITableViewScrollPositionTop animated:YES]

答案 1 :(得分:0)

不要使用reloadData,而是考虑执行批量更新reloadData将从您的dataSource加载新元素,但它也会产生副作用,即将您的scrollView的滚动位置重置为顶部。

你想要的是使用这种模式:

tableView.beginUpdates()
tableView.insertRowsAtIndexPaths([/* new rows here as an array of NSIndexPaths */], withRowAnimation: .Automatic)
tableView.endUpdates()

其中insertRowsAtIndexPaths包含您要添加的新行。