【问题标题】:UITableView -headerViewForSection returns (null)UITableView -headerViewForSection 返回(空)
【发布时间】:2014-10-28 00:59:00
【问题描述】:

我有一个 UITableView 有 2 个部分。每个都有自己的headerView
我通过-viewForHeaderInSection: 方法创建了一个自定义headerView
后来,我打算稍微修改一下,所以我需要使用viewForHeader方法,但是我无法访问headerView,它是subViews

作为一个简单的例子,我试图在-didSelectRowAtIndexPath:NSLog viewForHeader 对象,但我得到了(null) 结果。

示例代码:

-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    return 75;
}

-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{    
    UIView *myHeader = [[UIView alloc] init];
    switch (section) {
        case 0:
            [myHeader setBackgroundColor:[UIColor greenColor]];
            break;
        case 1:
            [myHeader setBackgroundColor:[UIColor redColor]];
            break;
        default:
            break;
    }

    UILabel *myLabel = [[UILabel alloc] init];
    [myLabel setFrame:CGRectMake(10, 0, 100, 30)];
    [myLabel setTag:101];
    [myLabel setBackgroundColor:[UIColor clearColor]];
    [myLabel setText:[NSString stringWithFormat:@"Section: %d",section]];

    [myHeader addSubview:myLabel];    
    return myHeader;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewHeaderFooterView *testView = [self.tableView headerViewForSection:indexPath.section];
    NSLog(@"%@",testView);  //displays (null)
}

我是否需要将自定义 UIView xib 创建为 headerView? (因为根据 similar question 和文档“)

要让表格视图识别您的页眉或页脚视图,您需要注册它。
您可以使用 registerNib:forCellReuseIdentifier: 或
registerClass:forCellReuseIdentifier:UITableView的方法。

【问题讨论】:

    标签: ios objective-c uitableview


    【解决方案1】:

    方法一:

    好的,经过反复试验,我终于解决了自己的困境。
    我做了headerView,就像我做一个单元格一样。

    对于单元格,我们将使用 UITableViewCell 并使用 dequeueReusableCellWithIdentifier
    同时...
    对于页眉/页脚,我们将采用UITableViewHeaderFooterView 并使用dequeueReusableHeaderFooterViewWithIdentifier 方法。

    其余部分与单元格的概念几乎相同。

    先决条件:

    1. 将标题高度设置为 40
    2. 将节数设置为 2 个或更多
    3. 将每个部分的行数设置为至少 1
    4. iOS6+(UITableViewHeaderFooterView 不适用于 iOS5 及更低版本

    第一种方法:

    -viewForHeaderInSection: 方法中创建和使用默认UITableViewHeaderFooterView

    - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
    {
        static NSString *HeaderIdentifier = @"header";
    
        UITableViewHeaderFooterView *myHeader = [tableView dequeueReusableHeaderFooterViewWithIdentifier:HeaderIdentifier];
        if(!myHeader) {
            myHeader = [[UITableViewHeaderFooterView alloc] initWithReuseIdentifier:HeaderIdentifier];
        }
    
        UIButton *btnUp = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        [btnUp setTag:101];
        [btnUp setTitle:@"-" forState:UIControlStateNormal];
        [btnUp setFrame:CGRectMake(tableView.frame.size.width - 35, 5, 30, 30)];
        [myHeader addSubview:btnUp];
    
        [myHeader.textLabel setText:[NSString stringWithFormat:@"Section: %d",section]];
    
        [myHeader setFrame:CGRectMake(0, 0, tableView.frame.size.width, 50)];
        return myHeader;
    }
    
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        UITableViewHeaderFooterView *theHeaderView = [tableView headerViewForSection:indexPath.section];
        NSLog(@"%@",theHeaderView); // -- great! ... not (null) anymore
    
        UIButton *theButton = (UIButton *)[theHeaderView viewWithTag:101];
        [theButton setTitle:@"+" forState:UIControlStateNormal];
    }
    

    第二种方法:

    使用自定义 UITableViewHeaderFooterView 子类:

    1. 创建了一个UITableViewHeaderFooterView 子类并将其命名为CustomHeaderView
    2. 为该类创建了一个 View 界面 nib 文件
    3. 在 xib 中,选择 View & 在它的 Identity Inspector
      • 自定义类指定为CustomHeaderView
    4. 制作属性,在xib中合成并连接它们
      • @property (strong, nonatomic) IBOutlet UILabel *lblSomething;
      • @property (strong, nonatomic) IBOutlet UIButton *btnSomething;

    -viewForHeaderInSection: & -didSelectRowAtIndexPath: 修改为:

    - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
    {
        static NSString *HeaderIdentifier = @"header";
    
        CustomHeaderView *myHeader = [tableView dequeueReusableHeaderFooterViewWithIdentifier:HeaderIdentifier];
        if(!myHeader) {
        //    [tableView registerClass:[CustomHeaderView class] forHeaderFooterViewReuseIdentifier:HeaderIdentifier];
            myHeader = [[[NSBundle mainBundle] loadNibNamed:@"CustomHeaderView"
                                                      owner:self
                                                    options:nil] objectAtIndex:0];
        }
    
        [myHeader.btnSomething setTitle:@"-" forState:UIControlStateNormal];
        [myHeader.lblSomething setText:[NSString stringWithFormat:@"Section: %d",section]];
    
        return myHeader;
    }
    
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        CustomHeaderView *theHeaderView = (CustomHeaderView*)[tableView headerViewForSection:indexPath.section];
        NSLog(@"%@",theHeaderView);
    
        [theHeaderView.lblSomething setAlpha:theHeaderView.lblSomething.alpha-0.1];
        [theHeaderView.btnSomething setTitle:@"+" forState:UIControlStateNormal];
    }
    

    PS:UITableViewHeaderFooterView 的问题在于它仅适用于 iOS6+,如果出于任何原因,您的标头是/必须是 UIView,那么请参阅下一个方法


    方法二:

    使用简单的UIView:

    -(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
    {
        UIView *vwHeader = [[UIView alloc] init];
        [vwHeader setTag:200 + section]; //[1] first method
    
        switch (section) {
            case 0:
                [vwHeader setBackgroundColor:[UIColor greenColor]];
                break;
            case 1:
                [vwHeader setBackgroundColor:[UIColor redColor]];
                break;
            default:
                break;
        }
    
        UILabel *lblTitle = [[UILabel alloc] init];
        [lblTitle setFrame:CGRectMake(10, 0, 100, 30)];
        [lblTitle setTag:100 + section]; //[2] alternative method
        [lblTitle setBackgroundColor:[UIColor clearColor]];
        [lblTitle setText:[NSString stringWithFormat:@"Section: %d",section]];
    
        [vwHeader addSubview:lblTitle];
        return vwHeader;
    }
    
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        UIView *vwTest = [self.tableView viewWithTag:200 + indexPath.section]; //[1]
        NSLog(@"[1] : %@",vwTest);
    
        //or
    
        UILabel *lblTest = (UILabel *)[self.tableView viewWithTag:100 + indexPath.section]; //[2]
        NSLog(@"%@",lblTest.text);
        UIView *vwTestForSuperview = lblTest.superview;
        NSLog(@"[2] : %@",vwTestForSuperview);
    }
    

    PS:我知道这段代码没有什么伟大的用途,但这只是其他人的一个例子。

    【讨论】:

    • 很好的回复..第二种方法对我来说效果很好.. :)
    • @staticVoidMan 在第一种方法中,删除子视图也很重要,因为标题出队,否则子视图将添加到已经添加的子视图上。在您的情况下,应首先删除 btnUp(如果存在),然后将其添加到子视图
    • 哎呀终于!我喜欢第二种方法。在这里完美运行。谢谢!
    【解决方案2】:

    我认为你的问题很容易解决:

    -(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
    {    
    UITableViewHeaderFooterView *myHeader = [[UITableViewHeaderFooterView alloc] init];
    switch (section) {
        case 0:
            [myHeader setBackgroundColor:[UIColor greenColor]];
            break;
        case 1:
            [myHeader setBackgroundColor:[UIColor redColor]];
            break;
        default:
            break;
    }
    
    UILabel *myLabel = [[UILabel alloc] init];
    [myLabel setFrame:CGRectMake(10, 0, 100, 30)];
    [myLabel setTag:101];
    [myLabel setBackgroundColor:[UIColor clearColor]];
    [myLabel setText:[NSString stringWithFormat:@"Section: %d",section]];
    
    [myHeader addSubview:myLabel];    
    return myHeader;
    

    }

    基本上,您需要使用 UITableViewHeaderFooterView 类从 viewForHeaderInSection 回调中返回。之后,在表视图上调用 headerViewForSection 将返回有效的对象实例而不是 nil。

    【讨论】:

    • 是的,我最近想通了。我实际上也将其作为答案发布在这里。我什至不得不转储-setBackgroundColor,因为UITableViewHeaderFooterView 不支持它。另外,UITableViewHeaderFooterView 提供了默认的textLabel,所以我也抛弃了UILabel
    【解决方案3】:

    你需要设置框架。

    -(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
    {    
        UIView *myHeader = [[UIView alloc] init];
        myHeader.frame   = CGRectMake(0, 0, 100, 75); //ADD THIS AND SET YOUR FRAME
        switch (section) {
            case 0:
                [myHeader setBackgroundColor:[UIColor greenColor]];
                break;
            case 1:
                [myHeader setBackgroundColor:[UIColor redColor]];
                break;
            default:
                break;
        }
    
        UILabel *myLabel = [[UILabel alloc] init];
        [myLabel setFrame:CGRectMake(10, 0, 100, 30)];
        [myLabel setTag:101];
        [myLabel setBackgroundColor:[UIColor clearColor]];
        [myLabel setText:[NSString stringWithFormat:@"Section: %d",section]];
    
        [myHeader addSubview:myLabel];    
        return myHeader;
    }
    

    【讨论】:

    • 实际上,根据我的观察,返回的UIView 对象的框架并不重要。如果你观察myHeader.frame.size.width的最终结果,它不会是100。它会等于tableView.frame.size.width。试试[myHeader setFrame:CGRectMake(10,10,10,10);不会有什么不同,因为视图是作为主要的headerView 返回的,而不是作为某些预先存在的headerView 的子视图。无论如何,为myHeader 设置框架仍然无法解决问题。
    猜你喜欢
    • 2016-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多