Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/94.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 在tableView中重新加载后保持滚动位置_Ios_Objective C_Uitableview_Uiscrollview_Uiscrollviewdelegate - Fatal编程技术网

Ios 在tableView中重新加载后保持滚动位置

Ios 在tableView中重新加载后保持滚动位置,ios,objective-c,uitableview,uiscrollview,uiscrollviewdelegate,Ios,Objective C,Uitableview,Uiscrollview,Uiscrollviewdelegate,我有一个桌面视图。当用户点击其中一条记录时,我会检查它的属性,并以此为基础过滤结果,只显示类似的结果——所以我需要刷新tableView 问题是用户可以上/下滚动tableView。我需要滚动tableView,使单元格与刷新前的位置完全相同 显然,我正在保存最后一个点击的项目 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { _lastSelecte

我有一个桌面视图。当用户点击其中一条记录时,我会检查它的属性,并以此为基础过滤结果,只显示类似的结果——所以我需要刷新tableView

问题是用户可以上/下滚动tableView。我需要滚动tableView,使单元格与刷新前的位置完全相同

显然,我正在保存最后一个点击的项目

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    _lastSelectedItem = [self itemForIndexPath:indexPath];
} 
然后在重新加载tableView之后:

NSIndexPath *indexPath = [self indexPathForItem:_lastSelectedItem];
if (_tableView.numberOfSections > indexPath.section && [_tableView numberOfRowsInSection:indexPath.section] > indexPath.row) {
    [_tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionMiddle animated:NO];
    _lastSelectedItem = nil;
}
那很好,但是。。。用户无法在
UITableViewScrollPositionMiddle
处完成。他可以在
UITableViewScrollPositionTop
UITableViewScrollPositionBottom
或两者之间的某个位置完成滚动

--编辑--


通过偏移量计算也有问题,因为偏移量是视图开始位置和顶部表格滚动位置之间的差异。。虽然我对这个值不感兴趣:/。

因为我的结构非常复杂,所以我用这种方式完成了它(例如,可扩展部分等)。请注意,我正在保存
\u lastSelectedItem
,这是我在数据源中的对象,因为刷新后indexPath将更改

- (void)refresh {
    [self saveLastScrollPosition];
    [self reloadData]; // inside we reload data + reload tableView
    [self scrollToLastScrollPosition];
}

- (NSInteger)heightToMinYOfCellAtIndexPath:(NSIndexPath *)indexPath {
    NSInteger sections = indexPath.section;
    NSInteger totalRows = 0;
    for (NSInteger section = 0; section < indexPath.section; section++) {
        totalRows += [self.tableView numberOfRowsInSection:section];
    }
    totalRows += indexPath.row;

    return ((sections + 1) * kHeaderHeight + totalRows * kRowHeight);
}

- (void)saveLastScrollPosition {
    if (_lastSelectedItem) { // make sure we have that item selected
        NSIndexPath *indexPath = [self itemForItem:_lastSelectedItem];
        NSInteger aboveItemHeight = [self heightToMinYOfCellAtIndexPath:indexPath];
        CGFloat contentOffsetY = self.tableView.contentOffset.y;
        _previousOffset = aboveItemHeight - contentOffsetY;
    }
}

- (void)scrollToLastScrollPostion {
    if (_lastSelectedItem) { // make sure we have that item selected
        NSIndexPath *indexPath = [self itemForItem:_lastSelectedItem];
        if (self.tableView.numberOfSections > indexPath.section && [self.tableView numberOfRowsInSection:indexPath.section] > indexPath.row) { // make sure the indexPath still exist after reload
            NSInteger aboveItemHeight = [self heightToMinYOfCellAtIndexPath:indexPath]; // height of items above selected index
            CGPoint offset = CGPointMake(0.f, aboveItemHeight - _previousOffset);
            // in case index should be higher: eg earlier item was at index (4,8) now is at (0,0)
            if (offset.y < 0) {
                offset.y = 0;
            }
            [self.tableView setContentOffset:offset animated:NO]; // just jump, user shouldn't see this
            _previousOffset = 0; // forget the calculated values
            _lastSelectedItem = nil;
        }
    }
}
-(无效)刷新{
[自救位置];
[self-reloadData];//在内部我们重新加载数据+重新加载tableView
[自滚动至最后滚动位置];
}
-(NSInteger)HeightToMinyOfcellateIndeXPath:(NSIndexPath*)indexPath{
NSInteger sections=indexPath.section;
NSInteger totalRows=0;
对于(NSInteger section=0;sectionindexPath.section&&[self.tableView numberofrowsinssection:indexPath.section]>indexPath.row){//请确保重新加载后indexPath仍然存在
NSInteger UpperItemHeight=[self-HeightToMinyOfcellateIndeXPath:indexPath];//高于所选索引的项目高度
CGPoint offset=CGPointMake(0.f,高于itemheight-\u先前的offset);
//如果指数应该更高:例如,之前的项目在指数(4,8)处,现在在(0,0)处
if(偏移量y<0){
偏移量y=0;
}
[self.tableView setContentOffset:offset-animated:NO];//只需跳转,用户不应该看到这个
_previousOffset=0;//忘记计算值
_lastSelectedItem=nil;
}
}
}

可以使用单个“reloadDataAndScrollToLastPosition”公共方法将其放入UITableView类别。如果假设UITableView单元格高度动态,并且标题也是动态的,我们将使用多个自定义单元格,那么我们可以做什么,请解释………@JatiendarKumar解释取决于您是如何实现它的。您可以在页面中间看到这样的方法
HeightForBasicCellatingXPath:
,并以它为例。这是一篇重复的文章:-行得通!(Y)