我有一个UITableView有两个部分。这是一个简单的表格视图。我正在使用viewForHeaderInSection为这些标头创建自定义视图。到目前为止,非常好。
默认的滚动行为是,遇到某个部分时,部分标题会一直停留在导航栏下方,直到下一部分滚动到视图中。
我的问题是:我可以更改默认行为,以便章节标题不会停留在顶部,而是在导航栏下滚动剩下的部分行吗?
我错过了一些明显的东西吗?
感谢。
答案 0 :(得分:173)
我解决此问题的方法是根据contentOffset
中的contentInset
调整UITableViewControllerDelegate
(扩展UIScrollViewDelegate
),如下所示:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGFloat sectionHeaderHeight = 40;
if (scrollView.contentOffset.y<=sectionHeaderHeight&&scrollView.contentOffset.y>=0) {
scrollView.contentInset = UIEdgeInsetsMake(-scrollView.contentOffset.y, 0, 0, 0);
} else if (scrollView.contentOffset.y>=sectionHeaderHeight) {
scrollView.contentInset = UIEdgeInsetsMake(-sectionHeaderHeight, 0, 0, 0);
}
}
这里唯一的问题是当滚动回顶部时它会失去一点反弹。
{注意:“40”应该是您的0部分标题的确切高度。如果您使用的数字大于第0部分标题高度,您会看到手指感觉受到影响(尝试“1000”,您会看到反弹行为在顶部有点奇怪)。如果数字符合你的0部分标题高度,手指感觉似乎是完美的或接近完美的。}
答案 1 :(得分:86)
您还可以在顶部添加一个零行的部分,只需使用上一部分的页脚作为下一部分的标题。
答案 2 :(得分:35)
如果我这样做,我会利用这样一个事实,即Plain样式中的UITableViews具有粘性标题,而Grouped样式中的UITableViews则没有。我可能至少尝试使用自定义表格单元模仿Grouped表格中普通单元格的外观。
我实际上没有尝试过,所以它可能无法正常工作,但这就是我的建议。
答案 3 :(得分:28)
我知道它来得很晚,但我找到了明确的解决方案!
您要做的是如果您有10个部分,请让dataSource返回20.对部分标题使用偶数,为部分内容使用奇数。像这样的东西
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (section%2 == 0) {
return 0;
}else {
return 5;
}
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if (section%2 == 0) {
return [NSString stringWithFormat:@"%i", section+1];
}else {
return nil;
}
}
瞧! :d
答案 4 :(得分:15)
以非黑客的方式解决这个问题需要做几件事:
UITableViewStyleGrouped
backgroundColor
设置为[UIColor clearColor]
backgroundView
设置为backgroundColor [UIColor clearColor]
rowHeight
,或者如果各行的高度不同,则覆盖tableView:heightForRowAtIndexPath:
。答案 5 :(得分:15)
最初发布Here,使用IB的快速解决方案。同样可以通过编程方式完成,但非常简单。
实现这一目标的更简单方法(使用IB):
将UIView拖到TableView上,使其成为标题视图。
- 将标题视图高度设置为100px
- 将tableview contentInset(顶部)设置为-100
- 节标题现在将像任何常规单元格一样滚动。
醇>
有些人评论说这个解决方案隐藏了第一个标题,但是我没有注意到任何这样的问题。它对我来说非常合适,是迄今为止我见过的最简单的解决方案。
答案 6 :(得分:14)
到目前为止,我对这里描述的解决方案不满意,所以我尝试将它们结合起来。结果是以下代码,受@awulf和@cescofry的启发。它适用于我,因为我没有真正的表视图标题。如果您已有表格视图标题,则可能需要调整高度。
// Set the edge inset
self.tableView.contentInset = UIEdgeInsetsMake(-23.0f, 0, 0, 0);
// Add a transparent UIView with the height of the section header (ARC enabled)
[self.tableView setTableHeaderView:[[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 100.0f, 23.0f)]];
答案 7 :(得分:14)
只需更改TableView样式:
self.tableview = [[UITableView alloc] initwithFrame:frame style:UITableViewStyleGrouped];
UITableViewStyle Documentation:
UITableViewStylePlain- 普通的桌面视图。任何节头或页脚都显示为内联分隔符,并在滚动表视图时浮动。
UITableViewStyleGrouped- 一个表视图,其中的部分显示不同的行组。部分页眉和页脚不会浮动。
答案 8 :(得分:6)
答案 9 :(得分:5)
更改TableView样式:
self.tableview = [[UITableView alloc] initwithFrame:frame style:UITableViewStyleGrouped];
根据UITableView的Apple文档:
UITableViewStylePlain-普通表视图。任何部分标题或 页脚显示为内联分隔符并在表格中浮动 视图滚动。
UITableViewStyleGrouped-一个表格视图,其截面显示不同 行组。节标题和页脚不会浮动。希望 这个小小的改变会帮助你..
答案 10 :(得分:4)
使用透明视图设置表格的headerView,并在剖面视图中使用相同的标题高度。同时使用-height的y框架初始化tableview。
self.tableview = [[UITableView alloc] initWithFrame:CGRectMake(0, - height, 300, 400)];
UIView *headerView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, width, height)] autorelease];
[self.tableView setTableHeaderView:headerView];
答案 11 :(得分:4)
我发现了一个替代解决方案,使用每个部分的第一个单元而不是真正的标题部分,这个解决方案看起来不那么干净,但是工作得很好,你可以使用定义的原型单元格作为标题部分,并且方法 cellForRowAtIndexPath 请求indexPath.row == 0,如果为true,则使用标题部分原型单元格,否则使用默认的原型单元格。
答案 12 :(得分:2)
现在分组的样式看起来与iOS 7中的普通样式基本相同(就平面度和背景而言),对我们来说,最好和最简单(即最少hacky)的修复就是简单地改变表格视图&#39; s样式分组。当我们在顶部集成滚动导航栏时,使用contentInsets进行插入总是一个问题。使用分组的表视图样式,它看起来完全相同(使用我们的单元格)并且节标题保持不变。没有滚动的怪异。
答案 13 :(得分:1)
为tableView指定负插入。如果您有22px高节标题,并且您不希望它们是粘滞的,请在重新加载数据后立即添加:
self.tableView.contentInset = UIEdgeInsetsMake(-22, 0, 0, 0);
self.tableView.contentSize = CGSizeMake(self.tableView.contentSize.width, self.tableView.contentSize.height+22);
对我来说就像一个魅力。也适用于部分页脚,只需在底部指定负插入。
答案 14 :(得分:0)
检查我的回答here。这是实现非浮动节头的最简单方法 没有任何黑客攻击。
答案 15 :(得分:0)
快速版的@awulf答案,效果很好!
func scrollViewDidScroll(scrollView: UIScrollView) {
let sectionHeight: CGFloat = 80
if scrollView.contentOffset.y <= sectionHeight {
scrollView.contentInset = UIEdgeInsetsMake( -scrollView.contentOffset.y, 0, 0, 0)
}else if scrollView.contentOffset.y >= sectionHeight {
scrollView.contentInset = UIEdgeInsetsMake(-sectionHeight, 0, 0, 0)
}
}
答案 16 :(得分:0)
更改TableView样式:
self.tableview = [[UITableView alloc] initwithFrame:frame style:UITableViewStyleGrouped];
根据UITableView的Apple文档:
UITableViewStylePlain- A plain table view. Any section headers or footers are displayed as inline separators and float when the table view is scrolled.
UITableViewStyleGrouped- A table view whose sections present distinct groups of rows. The section headers and footers do not float.
Hope this small change will help you ..
答案 17 :(得分:0)
@ LocoMike的答案最适合我的tableView,但是在使用页脚时它也破了。 因此,这是使用页眉和页脚时更正的解决方案:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return (self.sections.count + 1) * 3;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (section % 3 != 1) {
return 0;
}
section = section / 3;
...
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
if (section % 3 != 0) {
return nil;
}
section = section / 3;
...
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
if (section % 3 != 0) {
return 0;
}
section = section / 3;
...
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
if (section % 3 != 2) {
return 0;
}
section = section / 3;
...
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
if (section % 3 != 0) {
return nil;
}
section = section / 3;
...
}
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
if (section % 3 != 2) {
return nil;
}
section = section / 3;
...
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
int section = indexPath.section;
section = section / 3;
...
}
答案 18 :(得分:0)
我将表格添加到滚动视图中,这似乎运作良好。
答案 19 :(得分:-2)
我已经知道只需设置tableHeaderView属性就可以了,即:
tableView.tableHeaderView = customView;
就是这样。