就像在本机iOS Mail应用程序中一样,当我将UITableViewController推送到UINavigationController上时,我想使UITableView最初略微向下滚动,遮挡导航控制器导航栏下方的headerView。
同时,即使所有单元格的高度小于表视图的高度,用户也应该可以上下滚动以再次显式显示或隐藏标题视图。
有了这个逻辑,似乎要为此实现考虑两个因素:
1) 确保表格视图的最小内容大小至少为表格视图框架的高度 + 标题视图的高度。
2) 最初显示表视图时,内容偏移量将按标题视图的高度递增。
我尝试在"viewWillAppear"中手动设置表视图的 contentOffset 和 contentSize 属性,但这似乎没有效果(在此之后表视图可能会重新加载)。尝试将它们设置为"viewDidAppear"将起作用,但这为时已晚,因为只有在"推送"动画完成后才会调用它。
虽然以前的iOS版本之前已经问过这种问题,但我无法让它们中的任何一个在iOS 8中工作。此外,它们都涉及更改偏移量,而不是更改表视图的内容大小。
以前有没有人在iOS 7和/或8中遇到过这种行为?
更新 - (30/1/2015)
好。昨晚这对我来说不太好,所以我又玩了一遍,我找到了一个更好、更干净的解决方案。
我发现UITableViewController
的tableView
属性不是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"。