问题很简单:如何从Xib文件加载自定义UITableViewCell ?这样做允许您使用Interface Builder来设计单元格。由于内存管理问题,答案显然并不简单。这个帖子提到了这个问题,并提出了一个解决方案,但是在nda发布之前,缺乏代码。这里有一个很长的帖子,讨论了这个问题,但没有提供明确的答案。

下面是我使用的一些代码:

static NSString *CellIdentifier = @"MyCellIdentifier";

MyCell *cell = (MyCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:self options:nil];
    cell = (MyCell *)[nib objectAtIndex:0];
}

要使用这段代码,创建MyCell.m/.h,这是UITableViewCell的一个新子类,并为您想要的组件添加iboutlet。然后创建一个新的“Empty XIB”文件。在IB中打开Xib文件,添加一个UITableViewCell对象,将其标识符设置为“MyCellIdentifier”,并将其类设置为MyCell并添加组件。最后,将iboutlet连接到组件。注意,我们没有在IB中设置文件的所有者。

其他方法主张设置文件的所有者,如果Xib没有通过额外的工厂类加载,则警告内存泄漏。我在Instruments/Leaks下测试了上面的内容,没有发现内存泄漏。

那么从xib加载单元格的规范方法是什么呢?我们设置文件的所有者吗?我们需要工厂吗?如果是,工厂的代码是什么样子的?如果有多种解决方案,让我们来阐明每一种方案的优缺点。


当前回答

下面是我的方法:从XIB文件加载自定义UITableViewCells

这个想法是创建一个UITableViewCell的SampleCell子类,它带有一个IBOutlet UIView *content属性和一个用于您需要从代码中配置的每个自定义子视图的属性。然后创建一个SampleCell。xib文件。在这个nib文件中,将文件所有者更改为SampleCell。添加一个内容UIView大小,以适应您的需要。添加和配置你想要的所有子视图(标签、图像视图、按钮等)。最后,将内容视图和子视图链接到文件所有者。

其他回答

为此,我在控制器类中声明了一个IBOutlet UITableViewCell *单元格。 然后调用NSBundle loadNibNamed类方法,它将把UITableViewCell提供给上面声明的单元格。

对于xib,我将创建一个空的xib,并在IB中添加UITableViewCell对象,它可以根据需要进行设置。然后,该视图连接到控制器类中的单元IBOutlet。

- (UITableViewCell *)tableView:(UITableView *)table
         cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"%@ loading RTEditableCell.xib", [self description] );

    static NSString *MyIdentifier = @"editableCellIdentifier";
    cell = [table dequeueReusableCellWithIdentifier:MyIdentifier];

    if(cell == nil) {
        [[NSBundle mainBundle] loadNibNamed:@"RTEditableCell"
                                      owner:self
                                    options:nil];
    }

    return cell;
}

NSBundle添加loadNibNamed (ADC登录)

cocoawithlove.com文章我的概念来源(获取电话号码示例应用程序)

我不知道是否有一个规范的方法,但以下是我的方法:

为ViewController创建一个xib 将File Owner类设置为UIViewController 删除视图并添加一个UITableViewCell 将UITableViewCell的类设置为自定义类 设置UITableViewCell的标识符 设置你的视图控制器视图的出口到你的UITableViewCell

并使用这段代码:

MyCustomViewCell *cell = (MyCustomViewCell *)[_tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
  UIViewController* c = [[UIViewController alloc] initWithNibName:CellIdentifier bundle:nil];
  cell = (MyCustomViewCell *)c.view;
  [c release];
}

在你的例子中,使用

[nib objectAtIndex:0]

如果苹果改变xib中项目的顺序,可能会中断。

正确的解是这样的

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self.tableView registerNib:[UINib nibWithNibName:@"CustomCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"CustomCell"];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    UITableViewCell  *cell = [tableView dequeueReusableCellWithIdentifier:@"CustomCell"];
    return cell; 
    }

如果您正在使用Interface Builder来创建单元格,请检查是否在检查器中设置了标识符。然后在调用dequeueReusableCellWithIdentifier时检查是否相同。

我无意中忘记在一个表较多的项目中设置一些标识符,性能变化就像白天和黑夜一样。

从UITableViewCell创建自己的自定义类AbcViewCell子类(确保你的类文件名和nib文件名是相同的) 创建这个扩展类方法。 扩展UITableViewCell { class func fromNib<T: UITableViewCell>() -> T { Bundle.main返回。loadNibNamed(字符串(描述:T.self),所有者:nil,选项:nil)?[0]一样!T } } 使用它。 let cell: AbcViewCell = UITableViewCell.fromNib()