调整tableview的第一个可见节标题高度

时间:2013-04-06 16:54:29

标签: iphone ios objective-c uitableview

我创建了一个包含自定义节标题视图的UITableView。现在,我希望它在最上面的当前可见部分显示更多数据。我计划使用事件scrollViewDidEndDecelerating来更新节标题。目前,问题是我无法为特定的节号设置节标题高度。

我之前尝试过使用heightForHeaderInSection,但该应用只是崩溃了以下输出:

'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array'

我正在使用代码:

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    if (tableView == self.tableView)
    {
        NSArray *visibleCells = [self.tableView visibleCells];
        NSMutableArray *visibleSections = [[NSMutableArray alloc] init];
        for (NSInteger index = 0; index < [visibleCells count]; index++)
        {
            UITableViewCell *currentCell = [visibleCells objectAtIndex:index];
            NSIndexPath *currentPath = (NSIndexPath *)[self.tableView indexPathForCell:currentCell];
            if (![visibleSections containsObject:[NSNumber numberWithInt:currentPath.section]])
            {
                [visibleSections addObject:[NSNumber numberWithInt:currentPath.section]];
                NSLog([NSString stringWithFormat:@"%ld", (long)[visibleSections count]]);
                [visibleSections sortedArrayUsingDescriptors:[NSArray arrayWithObject:[[NSSortDescriptor alloc] initWithKey:nil ascending:YES]]];
            }
        }
        if (visibleSections == nil)
        {
            return 42.0;
        }
        else if ([[visibleSections objectAtIndex:0] integerValue] == section)
        {
            return 58.0;
        }
        else
        {
            return 42.0;
        }
    }
}

我无法弄清楚我的heightForHeaderInSection方法出了什么问题,但我知道它与NSMutableArray,visibleSections有关。

关于我如何更改heightForHeaderInSection之外的特定部分标题视图的高度和/或我如何修复上述代码的任何提示或答案都非常有帮助。

修改

为了让我的崩溃问题的解决方案更加清晰,if (visibleSections == nil)不应该用来代替if ([visibleSections count] < 1)if ([visibleSections count] == 0)

4 个答案:

答案 0 :(得分:1)

我认为你也可以这样做,如果你希望第一个节头在表格首次出现时更高(topSection是一个NSInteger属性):

-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    self.topSection = ((NSIndexPath *)[self.tableView indexPathsForVisibleRows][0]).section;
    [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:self.topSection] withRowAnimation:NO];
}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {

        if (self.topSection == section)
        {
            return 58.0;
        }
        else
        {
            return 42.0;
        }
}

答案 1 :(得分:0)

你不能通过调用objectAtIndex:0来直接引用数组第一个对象,你必须保持防御所以改变这个:

else if ([[visibleSections objectAtIndex:0] integerValue] == section)
    {
        return 58.0;
    }

else if([visibleSections count]>0)
    {
      if ([[visibleSections objectAtIndex:0] integerValue] == section)
        {
           return 58.0;
        }
     }

答案 2 :(得分:0)

好的,事实证明这是一个比最初看起来更难的问题。我到目前为止所提出的最好的是

  • 不要将顶部的标题视为任何不同的标题,并使用额外的数据填充它们。
  • 您可以通过巧妙地定位“附加”项目来显示和隐藏不同的部分,以便它们在较小的时候位于父视图的边界之外,并使父视图clipToBounds
  • 如果您无法创建自定义UIView子类并在layoutSubviews中执行某些操作

我正在解决的最终实施是

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
  NSArray *indexPaths = [self.tableView indexPathsForVisibleRows];
  self.topSection = [indexPaths count] ? [indexPaths[0] section] : -1;
  if (indexPaths.count > 1) {
    self.topSection = [indexPaths[1] section];
  }

  [self.tableView beginUpdates];
  [self.tableView endUpdates];
}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section;
{
  if (section <= self.topSection) {
    return 60;
  } else {
    return 20;
  }
}

这绝不是完美的,但看起来半合理,可以调整。

注意事项:

  • 您可能需要评估scrollViewDidScroll:中是否有太多工作正在进行,但它似乎并没有给我带来任何延迟(我没有真正测试过)
  • 我使用第二个indexPath设置了顶部,如果可用,因为它看起来更令人愉悦/更少笨重
  • 我使用section <= self.topSection因为之前的标题都是屏幕所以没有必要减少它们的大小,这会导致非常笨重的动画。

因此,在尝试此操作后,您可能需要深入挖掘或想要重新考虑您的设计

答案 3 :(得分:-1)

尝试更改此行:

NSMutableArray *visibleSections = [[NSMutableArray alloc] init]

为:

NSMutableArray *visibleSections = [NSMutableArray array];

初始化数组。