更改UITableView节标题的默认滚动行为

时间:2009-03-20 02:19:48

标签: ios iphone uitableview cocoa-touch

我有一个UITableView有两个部分。这是一个简单的表格视图。我正在使用viewForHeaderInSection为这些标头创建自定义视图。到目前为止,非常好。

默认的滚动行为是,遇到某个部分时,部分标题会一直停留在导航栏下方,直到下一部分滚动到视图中。

我的问题是:我可以更改默认行为,以便章节标题不会停留在顶部,而是在导航栏下滚动剩下的部分行吗?

我错过了一些明显的东西吗?

感谢。

20 个答案:

答案 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)

以非黑客的方式解决这个问题需要做几件事:

  1. 将表格视图样式设置为UITableViewStyleGrouped
  2. 将表格视图backgroundColor设置为[UIColor clearColor]
  3. 将每个表格视图单元格上的backgroundView设置为backgroundColor [UIColor clearColor]
  4. 的空白视图
  5. 如有必要,请相应地设置表格视图rowHeight,或者如果各行的高度不同,则覆盖tableView:heightForRowAtIndexPath:

答案 5 :(得分:15)

最初发布Here,使用IB的快速解决方案。同样可以通过编程方式完成,但非常简单。

  

实现这一目标的更简单方法(使用IB):

     

将UIView拖到TableView上,使其成为标题视图。

     
      
  1. 将标题视图高度设置为100px
  2.   
  3. 将tableview contentInset(顶部)设置为-100
  4.   
  5. 节标题现在将像任何常规单元格一样滚动。
  6.   

有些人评论说这个解决方案隐藏了第一个标题,但是我没有注意到任何这样的问题。它对我来说非常合适,是迄今为止我见过的最简单的解决方案。

答案 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)

Select Grouped TableView style

从情节提要中的tableView的属性检查器中选择分组表视图样式。

答案 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;

就是这样。