在运行iOS 6.1时,tableView:willDisplayHeaderView:inSection:未被调用。

7

我在stackoverflow上没有找到类似的问题,所以我会发布自己的问题(如果有不理解的地方,请告诉我):

问题:

我在自定义的UITableViewController中使用带有A-Z部分标题的常规索引tableView(如contacts.app中的那样)。 我重写了tableView:viewForHeaderInSection:来提供自己的部分标题视图。

当用户向上或向下滚动表格时,我需要监听出现/消失在tableView顶部或底部的部分标题(以相应地更改某些自定义视图)。

我重写了自从iOS 6.0以来可用的这些方法,它们正好可以做到这一点:

  1. tableView:didEndDisplayingHeaderView:forSection:

  2. tableView:willDisplayHeaderView:forSection:

2. 在向上/向下滚动tableView时从未被调用,而方法1每次部分标题从屏幕消失时都会被调用。

我不知道为什么一个会被调用而另一个不会。 这是苹果的错误还是我做错了什么?


类似问题:

我在这里找到了一个类似的问题如何在表视图自定义期间调用方法“willDisplayFooterView”?,其中一个答案是:

它们仅在iOS 6.0或更高版本下调用,而且只有在您还实现其他标题/页脚标题/视图方法时才会被调用。如果您提供标题或页脚,则无需调用这些方法。

我不确定我是否正确理解了这个答案,但如果是这样的话,似乎重要的是在子类中实现哪些方法。


代码:

我只发布了我的tableViewController中非空的覆盖委托和数据源方法:

tvcA.m

@implementation tvcA 
...
#pragma mark - Table view data source 

- (NSArray *) sectionIndexTitlesForTableView : (UITableView *) tableView 
{
    // returns sectionIndexArray with alphabet for example
}

- (UIView *) tableView : (UITableView *) tableView
viewForHeaderInSection : (NSInteger) section 
{
    MNSectionHeaderView* headerView = [[MNSectionHeaderView alloc] initWithFrame : CGRectMake(0, 0, 260, 22)];
    return headerView;
}

-     (NSInteger) tableView : (UITableView *) tableView
sectionForSectionIndexTitle : (NSString *) title
                    atIndex : (NSInteger) index {...}
...
@end

tvcB.h(继承自tvcA)

@interface tvcB : tvcA
...
@end

tvcB.m

@implementation tvcB
...
#pragma mark - Table view data source

- (NSInteger) numberOfSectionsInTableView : (UITableView *) tableView {...}

- (NSInteger) tableView : (UITableView *) tableView
  numberOfRowsInSection : (NSInteger) section {...}

- (UITableViewCell*) tableView : (UITableView *) tableView
      cellForRowAtIndexPath : (NSIndexPath *) indexPath {...}

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

- (UIView *) tableView : (UITableView *) tableView
viewForHeaderInSection : (NSInteger) section {....}


#pragma mark - Table view delegate

-    (void) tableView : (UITableView*) tableView
willDisplayHeaderView : (UIView*) view
       forSection : (NSInteger) section { 
    // custom configurations
}

-         (void) tableView : (UITableView*) tableView
didEndDisplayingHeaderView : (UIView*) view
                forSection : (NSInteger) section {
   // custom configurations    
}

- (void) tableView : (UITableView *) tableView
didSelectRowAtIndexPath : (NSIndexPath *) indexPath {...}
...
@end
2个回答

10

我现在明白了。

上面提到的类似问题已经给出了答案,但我没有理解正确:

[...] 如果您提供了一个标题或页脚,则不需要调用这些方法

(他可能是指我上面重写的两个方法。)

因为我提供了自己的段落标题,所以每次进入屏幕时都会调用另一个重写的方法tableView:viewForHeaderInSection:,而不是tableView:willDisplayHeaderView:forSection:方法。

因此,最后我将在最后提到的方法中进行所需的配置。


0
在我的情况下,由于我有一个带有许多表格的滚动视图,因此所有表格的所有部分都会调用tableView:viewForHeaderInSection:。因此,您的解决方案对我无效。但是,由于我只需要知道当VC弹出时第一个可见的部分是哪个,所以我想出了这个好的解决方案:
    NSInteger firstVisibleSection = 0;
    for (int i = 0; i < [_board.swimlanes count]; i++)
    {
        CGRect sectionRect = [currentTable rectForSection:i];
        BOOL containsPoint = CGRectContainsPoint(sectionRect, currentTable.contentOffset);
        if (containsPoint)
        {
            firstVisibleSection = i;
            break;
        }
    }

或许对于有同样问题的人会有所帮助 :)


我猜,你只想追踪屏幕上可见的最顶部的部分,对吗?当然:tableView:viewForHeaderInSection:每次一个部分标题重新出现在屏幕上时都会被调用 - 在顶部和/或底部。跟踪顶部部分的更简单的方法是:添加一个类属性,如 NSUInteger topSection,并在 tableView:viewForHeaderInSection: 中设置它,例如:if(section < _topSection){ _topSection = section;},在 tableView:didEndDisplayingHeaderView:forSection:nextSectionShown: 中,如果 section == _topSection,则 _topSection = nextSection;。试一下-这样更容易。 - anneblue
我试过了,不起作用。至少在我的情况下是这样的。 我有一个分页的scrollView,每一页都有一个表格。当视图首次出现时,tableView:viewForHeaderInSection:会被调用来获取所有headerView,而不仅仅是屏幕上的那些。 另外,根据你提出的解决方案,你一直跟踪section,而使用我上面发布的解决方案时,你只在需要时进行检查。 - AXE
1
好的,我认为两种解决方案(需要时检查/始终跟踪)在不同情况下可能都有帮助(在我的情况下,我需要那些信息一直更新)。只是因为我很好奇:当您的分页scrollView /表格第一次加载时,第一个部分“0”是否总是显示在顶部?顺便说一句:您知道可以检查哪个tableView方法tableView:viewForHeaderInSection:正在调用,例如:if (tableView == self.searchDisplayController.searchResultsTableView)... - anneblue
不,当VC加载时,我会聚焦于上一个会话中最后查看的泳道。这就是我需要这些信息的原因 ;) 也是为什么我只在最后需要它的原因。我并不是说我的解决方案是唯一的,但它对我来说是完美的,所以我在这里提供它。 - AXE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接