iOS 8 - 最初隐藏 UITableView 的标题从视图中查看



就像在本机iOS Mail应用程序中一样,当我将UITableViewController推送到UINavigationController上时,我想使UITableView最初略微向下滚动,遮挡导航控制器导航栏下方的headerView。

同时,即使所有单元格的高度小于表视图的高度,用户也应该可以上下滚动以再次显式显示或隐藏标题视图。

有了这个逻辑,似乎要为此实现考虑两个因素:

1) 确保表格视图的最小内容大小至少为表格视图框架的高度 + 标题视图的高度。

2) 最初显示表视图时,内容偏移量将按标题视图的高度递增。

我尝试在"viewWillAppear"中手动设置表视图的 contentOffset 和 contentSize 属性,但这似乎没有效果(在此之后表视图可能会重新加载)。尝试将它们设置为"viewDidAppear"将起作用,但这为时已晚,因为只有在"推送"动画完成后才会调用它。

虽然以前的iOS版本之前已经问过这种问题,但我无法让它们中的任何一个在iOS 8中工作。此外,它们都涉及更改偏移量,而不是更改表视图的内容大小。

以前有没有人在iOS 7和/或8中遇到过这种行为?

更新 - (30/1/2015)

好。昨晚这对我来说不太好,所以我又玩了一遍,我找到了一个更好、更干净的解决方案。

我发现UITableViewControllertableView属性不是readonly。因此,简单地管理UITableView子类中的contentSize属性,然后将该子类重新分配给UITableViewController实际上更有意义。

@implementation TOCustomTableView
- (void)setContentSize:(CGSize)contentSize
{
    CGFloat scrollInset = self.contentInset.top + self.contentInset.bottom;
    CGFloat height = (CGRectGetHeight(self.bounds) - scrollInset) + CGRectGetHeight(self.tableHeaderView.frame);
    contentSize.height = MAX(height, contentSize.height);
    [super setContentSize:contentSize];
}
@end
---
@implementation TOCustomTableViewController
- (void)viewDidLoad
{
    [super viewDidLoad];
    self.tableView = [[TOCustomTableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
}
@end

这样,表视图的最小contentSize始终显式设置为表视图的高度 + headerView 大小,从而在零抖动的情况下实现所需的效果。 :)


原始答案

技巧14为我指明了正确的方向。所以我最终得到了正常运行的代码。

- (void)resetTableViewInitialOffset
{
    CGPoint contentOffset = self.tableView.contentOffset;
    contentOffset.y = self.tableView.contentInset.top + CGRectGetHeight(self.headerView.frame);
    self.tableView.contentOffset = contentOffset;
}
- (void)resetTableViewContentSize
{
    CGSize contentSize = self.tableView.contentSize;
    CGFloat scrollInset = self.tableView.contentInset.top + self.tableView.contentInset.bottom;
    CGFloat height = (CGRectGetHeight(self.view.bounds) - scrollInset) + CGRectGetHeight(self.headerView.frame);
    contentSize.height = MAX(height, contentSize.height);
    self.tableView.contentSize = contentSize;
}
- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];
    if (!self.headerBarInitiallyHidden) {
        [self resetTableViewContentSize];
        [self resetTableViewInitialOffset];
        self.headerBarInitiallyHidden = YES;
    }
}

我还确保每次对表视图执行"重新加载数据"时都调用"resetTableViewContentSize"。

最新更新