UiTableView 标题没有消失

Posted

技术标签:

【中文标题】UiTableView 标题没有消失【英文标题】:UiTableView header not disappearing 【发布时间】:2017-10-05 14:14:55 【问题描述】:

我有一个 UITableView 配置为普通样式,因此我可以将标题视图卡在表格顶部,直到另一个标题将其拉走。

问题是:如果我有一个标题卡在屏幕顶部,并且我以编程方式滚动到表格的另一部分(该标题根本不应该出现的地方),那么 UIView 将不会被关闭。 IE。如果我再次滚动到表格的该部分,该标题的幽灵将在表格的该部分可见。

我已经实现了- (void)tableView:(UITableView *)tableView didEndDisplayingHeaderView:(nonnull UIView *)view forSection:(NSInteger)section 方法来了解正在发生的事情。我发现如果我手动滚动直到一个标题被拉离屏幕,这个委托就会被调用。但如果我以编程方式滚动,则不会调用委托。

顺便说一句,我尝试使用两种不同的方法以编程方式滚动,问题是一样的。

- (void)setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated;
- (void)scrollToRowAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UITableViewScrollPosition)scrollPosition animated:(BOOL)animated;

我可以想象的一种解决方法是实现- (void)scrollViewDidScroll:(UIScrollView *)scrollView;,过滤可见屏幕之外的所有标题视图,并将它们从超级视图中删除。我可能可以让它工作,但我想知道是否有其他更好的解决方案。

[编辑] 如果我用动画 = YES 调用 - (void)setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated;,则该错误不会发生。我可以使用这个解决方案,但在某些情况下我真的希望在没有动画的情况下滚动。

【问题讨论】:

如果将表格视图设置为分组非普通,是否会出现问题? 不,我刚刚测试过。当标题超出其“自然”位置(卡在表格顶部)时会出现问题,这不会在分组样式中发生。 ***.com/questions/5466097/… 这可能会为您指明正确的方向 我不这么认为。我没有在我的实现中使用 contentInset。 天哪,正如我所说,我使用[_conversationTableView setContentOffset:newOffset animated:mustAnimate]; 自动滚动表格。而且我刚刚意识到,如果动画是 YES,则错误不会发生!我将编辑问题以提及这一点。但此时,我只能认为是ios的bug。 【参考方案1】:

不完全确定我完全理解您的问题,但似乎您的标题视图(一些UIView)在您以编程方式滚动离开该区域/部分时/未正确呈现,然后然后强>回归。

我不确定您如何填充标题视图内容,但我有 几个 应用程序运行 UITableView 的多个部分标题需要更新滚动/内容偏移没有问题, 只要你用这个委托“绘制”你的标题:

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section 

    // Per section, simply return the appropriate header view

    ...

    NSString *someIdentifier = [NSString stringWithFormat:@"sectionHeaderView:<some #, letter, or tag>", <SOMETHING UNIQUE ADD HERE>];
    UITableViewHeaderFooterView *myHeaderView = [self.tableView dequeueReusableHeaderFooterViewWithIdentifier:someIdentifier];

    if (!myHeaderView) 

        // No header view found with that ID. Make a new one 

    

    ... 

    return myHeaderViewForSection;


这样,无论您是手指滚动还是以编程方式设置您喜欢的内容偏移量,您的表格视图都将知道要绘制什么、何时绘制以及放置在何处。

使用他们的代表有点麻烦,因为一开始有点乏味,但使用viewForHeaderInSection 证明是我获得我(你)想要的结果的唯一方法。

希望这会有所帮助 - 编码愉快!

【讨论】:

我正在使用这种方法。但是,也许我正在做一些我不应该做的事情。我在这个方法中设置了单元格的框架。 -(UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section ... view.frame = CGRectMake(0, 0, tableView.frame.size.width, view.frame.size.height); ... return view; 设置框架应该不是问题,只要它对所有单元格/部分保持不变。我会为每个UITableViewHeaderFooterView 使用“唯一”标识符,这样表真的知道哪个是哪个 每个 UITableViewHeaderFooterView 的唯一标识符是什么意思?你能给我一份文件来阅读它吗? 当然 - 这是 Apple 的文档:developer.apple.com/documentation/uikit/uitableview/… 我注意到,如果您为每个标题视图提供相同的 ID,比如说“sectionHeaderView”,表格可能会同时处理它看到的许多视图具有相同的重用ID,并不确定在哪里绘制什么。 我更新了我的答案,添加了更多关于我上面提到的内容的上下文 - 应该让事情更清楚:)【参考方案2】:

TL;DR

不要在beginUpdatesendUpdates 之间显式滚动表格视图。

说明

我正在使用 NSFetchedResultsController 来填充表格。这些是我对 NSFetchedResultsControllerDelegate 的一些方法的实现。

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller

    [_conversationTableView beginUpdates];


- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller

    [_conversationTableView endUpdates];

问题是 endUpdates 进行了一系列调用,最终调用了我的方法[self scrollToBottom](实际上这是一个非常丑陋的代码)。顾名思义,这个方法调用- (void)setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated; 将表格视图滚动到表格底部。

beginUpdates - endUpdates 期间显式滚动表格是我整个问题的罪魁祸首。

解决方案

仅在完成 ​​endUpdates 后滚动表格视图。

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller

    [_conversationTableView beginUpdates];


- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller

    [_conversationTableView endUpdates];

    [self scrollToBottom];

旁注

这也解决了表格视图在滚动时有时会闪烁的问题。

【讨论】:

【参考方案3】:

不应该出现的sectionHeader高度手动设置为0

tableView.sectionHeaderHeight = 0;

【讨论】:

以上是关于UiTableView 标题没有消失的主要内容,如果未能解决你的问题,请参考以下文章

不调用UITableView Delegate

UITable 视图项有时会在选择时消失(取决于屏幕大小)

将子视图添加到 UITable

UiTableView 标题没有消失

不要删除 UITable 的第一行

UITableView 不显示解析的数据