【问题标题】:Maintain offset when reloadRowsAtIndexPathsreloadRowsAtIndexPaths 时保持偏移
【发布时间】:2015-01-22 01:12:12
【问题描述】:

我正在尝试重新加载单个 tableViewCell,但每次执行此操作时它都会滚动到顶部...我没有添加或删除单元格,我只是想更改所选单元格的颜色。

这就是我在 cellForRowAtIndexPath 中所做的:

SMPChoiceViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ChoiceCell" forIndexPath:indexPath];
SMPChoice *choice = self.choices[indexPath.row - 1];
cell.choiceTextLabel.text = choice.text;

if ([self.selectedChoices indexOfObject:choice] != NSNotFound) {
  cell.choiceTextLabel.textColor = [UIColor purpleColor];
} else {
  cell.choiceTextLabel.textColor = [UIColor blackColor];
}

这就是我在 didSelectRowAtIndexPath 中所做的

if ([self.selectedChoices indexOfObject:choice] != NSNotFound) {
  [self.selectedChoices removeObject:choice];
} else {
  [self.selectedChoices addObject:choice];
}

CGPoint offSet = [tableView contentOffset];

[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView setContentOffset:offSet animated:NO];

但它只是跳跃,有什么建议吗?

附言 我关注了这个帖子,但它没有解决我的问题Calling reloadRowsAtIndexPaths removes tableView contentOffset

【问题讨论】:

  • 尝试 UITableViewRowAnimationNone 并删除 [tableView setContentOffset:offSet animated:NO];
  • 嗨 Sathya... 它仍然滚动到顶部,现在它没有那么好的褪色效果嘿嘿嘿:'(

标签: ios uitableview reload


【解决方案1】:

OBJ-C版大牛的回答:

//rowHeightForIndexPath is an NSMutableDictionary
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    [self.rowHeightForIndexPath setObject:@(cell.frame.size.height) forKey:indexPath];
}

- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSNumber *cachedHeight = [self.rowHeightForIndexPath objectForKey:indexPath];

    return cachedHeight ? cachedHeight.floatValue : UITableViewAutomaticDimension;
}

【讨论】:

    【解决方案2】:

    由于某种神秘的原因,表格视图会在使用估计的行高重新加载某些单元格后确定新的偏移量,您希望确保 tableView:estimatedHeightForRowAtIndexPath 为已渲染的单元格返回正确的数据。为此,您可以将看到的行高缓存在字典中,然后使用此正确数据(或您对尚未加载的单元格的估计。)

    fileprivate var heightForIndexPath = [NSIndexPath: CGFloat]()
    fileprivate let averageRowHeight: CGFloat = 300 //your best estimate
    
    //UITableViewDelegate
    
    override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
        heightForIndexPath[indexPath] = cell.frame.height
    }
    
    override func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        return heightForIndexPath[indexPath] ?? averageRowHeight
    }
    

    (非常感谢 eyuelt 洞察到使用估计的行高来确定新的偏移量。)

    【讨论】:

    • 即使使用缓存的方法仍然有同样的问题。
    • 这对我来说是一个快速简单的解决方案。任何高估或低估细胞高度的方法似乎都始终如一。当表重新加载新数据时,我还清除了缓存。
    【解决方案3】:

    我知道这是一个老问题,但我遇到了同样的问题,在任何地方都找不到答案。

    reloadRowsAtIndexPaths:withRowAnimation: 之后,tableView 使用tableView:estimatedHeightForRowAtIndexPath: 中给出的估计高度来确定其偏移量。因此,除非您返回的值是准确的,否则执行它将导致您的 tableView 的偏移量在重新加载后发生变化。我未实现tableView:estimatedHeightForRowAtIndexPath:,问题已解决。

    【讨论】:

    • 文档状态:“如果您没有估计,则返回 UITableViewAutomaticDimension”tableView:estimatedHeightForRowAtIndexPath:。您应该返回它而不是不实施它。取消实现该方法会导致我的单元格给出不准确的高度
    • @Gee.E UITableViewAutomaticDimension 是在 iOS 8 中引入的。因此,如果您在 iOS 8 之前不需要支持任何东西,那么是的,您应该使用 UITableViewAutomaticDimension。我不确定为什么不实现该方法对您不起作用。
    • @Gee.E 即使返回 UITableViewAutomaticDimension 也只是一个小小的改进。 TableView 仍然会跳转到不同的位置。
    • 是的,UITableViewAutomaticDimension 不是为我做的。 ...也没有实现该方法。
    猜你喜欢
    • 2019-12-22
    • 2016-05-04
    • 1970-01-01
    • 1970-01-01
    • 2021-05-22
    • 2011-05-08
    • 2021-09-20
    • 2021-01-11
    • 2022-08-31
    相关资源
    最近更新 更多