【问题标题】:iOS 8 - Initially hide a UITableView's headerView from viewiOS 8 - 最初从视图中隐藏 UITableView 标题视图
【发布时间】:2015-03-28 07:41:07
【问题描述】:

就像在本机 iOS 邮件应用程序中一样,当我将 UITableViewController 推送到 UINavigationController 上时,我希望 UITableView 最初看起来略微向下滚动,从而遮挡了导航控制器导航栏下方的 headerView。

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

按照这个逻辑,这个实现似乎有两个考虑因素:

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

2) 最初呈现表格视图时,内容偏移量会增加标题视图的高度。

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

虽然以前的 iOS 版本已经问过这类问题,但我无法让它们中的任何一个在 iOS 8 中运行。此外,它们都处理了更改偏移量,而不是 table view 的 contentSize。

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

【问题讨论】:

  • viewDidLayoutSubviews上试试这个。
  • 哈哈,该死的。那行得通!我不敢相信我错过了!等一下,我会为这个问题写一个正确的答案。

标签: ios objective-c iphone uitableview uiscrollview


【解决方案1】:

更新 - (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

这样,table view 的最小contentSize 总是显式设置为 table view 的高度 + headerView 的大小,达到零抖动的预期效果。 :)


原答案

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

- (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;
    }
}

我还确保每次在表格视图上执行“reloadData”时都调用“resetTableViewContentSize”。

【讨论】:

  • 干净而出色的解决方案 +1
猜你喜欢
  • 2013-09-20
  • 2013-05-31
  • 2012-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-09
  • 2017-02-11
相关资源
最近更新 更多