如何重用单个xib作为tableview的节头?

时间:2014-01-06 20:16:05

标签: ios cocoa-touch uitableview

我想在我的tableview上利用Apple的锁定部分标题控件(部分标题粘在顶部,直到下一部分标题向上推),但我想使用我自己的视图,并且我是用xib设计的。

在我的应用程序的其他地方,我在代码中为部分标题创建视图,一切都很好,但是当尝试使用xib对视图执行相同的操作时,它会出现问题。

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    ProductSectionHeader* header = self.productHeaderView;
    if (!header)
    {
        [[NSBundle mainBundle] loadNibNamed:@"ProductSectionHeader" owner:self options:nil];
    }
    header.nameLabel.text = @"Some person";
    header.locationLabel.text = @"Some place";

    return header;
}

这显示了第一部分中的标题视图(每个单元格都有自己的部分),但是当提示显示第二个标题时,所有标题都会消失。似乎我只允许对xib或其他东西进行一次引用。

那么如何重用xib在一个控制器中创建该视图的多个实例,以及如何将其用于节头?

2 个答案:

答案 0 :(得分:2)

在您调用loadNibNamed:的行中,您没有对该行的结果执行任何操作。它返回一个NSArray,其中包含您未保存的xib文件中的视图。您永远不会将header设置为if语句中的任何内容。假设xib只包含你想要的UIView,你可能希望从该数组中得到索引为0的项。

此外,您首先看到标题的事实意味着self.productHeaderView已经设置为代码中的其他位置,所以它永远不会进入您的if语句。所以我猜你正在看到你看到的问题,因为它试图使用与每个部分的标题相同的UIView,并且它会导致问题,因为它试图将它放在多个位置。 / p>

如果你想解决这个问题,请确保你为每个部分使用一个唯一的UIView,所以你不应该试图像你一样在实例变量中存储和检索单个UIView,除非你只有一个部分。您可以用NSMutableDictionary替换它,这样您只需为每个部分创建和存储一次标题,后续调用它只会从字典中检索它。

答案 1 :(得分:2)

  

那么如何重用xib来创建该视图的多个实例呢?   一个控制器,我如何将其用于节标题?

每次加载.xib时都会创建一个新的视图副本。诀窍是将新加载的视图保存在不同的属性或变量中,然后清除连接到视图的插座,以便加载另一个副本。所以,这样的事情,假设productHeaderView是连接到标题视图的出口:

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    // load the view from the .xib
    [[NSBundle mainBundle] loadNibNamed:@"ProductSectionHeader" owner:self options:nil];

    // save it in a different variable
    ProductSectionHeader* header = self.productHeaderView;

    // clear the outlet for next time
    self.productHeaderView = nil;

    if (!header)
    {
        NSLog(@"There was a problem loading the view.")
    }
    header.nameLabel.text = @"Some person";
    header.locationLabel.text = @"Some place";

    return header;
}

我还应该指出相对较新的UITableView方法-registerNib:forHeaderFooterViewReuseIdentifier:,这使得事情变得更加容易。你可以只用表注册一个nib对象,让表担心加载视图。表格单元格有类似的方法。